Reflektor ist dein Freund auf diesem. Der Code generiert für Ihre zweite Zeile sieht etwa so aus (ungefähr):
if(Binder.IsEvent("OnMyEvent", typeof(SomeWrapperClass)))
{
Binder.InvokeMember("add_OnMyEvent", obj, myAction);
}
else
{
var e = Binder.GetMember("OnMyEvent", obj);
var ae = Binder.BinaryOperation(ExpressionType.AddAssign, e, myAction);
Binder.SetMember("OnMyEvent", obj, ae);
}
Wenn Sie kein reales Ereignis für OnMyEvent
verwenden können (in diesem Fall, dass Sie auf der Standard-DynamicObject
Implementierung anlehnen kann), dann sind Sie‘ Ich muss etwas zurückgeben, das AddAssign
implementiert, etwas wie ein Multicastdelegat zurückzugeben. Ich würde die ehemalige vorschlagen, wenn möglich ...
Für Spaß, hier ist ein hackish Beispiel, das dynamisch OnMyEvent zu OnMyOtherEvent bindet:
public class SomeWrapperClass : DynamicObject
{
public event Action OnMyOtherEvent;
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (binder.Name == "OnMyEvent")
{
result = OnMyOtherEvent;
return true;
}
return base.TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (binder.Name == "OnMyEvent" && value is Action)
{
OnMyOtherEvent = (Action)value;
return true;
}
return TrySetMember(binder, value);
}
public void Test()
{
if (OnMyOtherEvent != null)
OnMyOtherEvent();
}
private static void TestEventHandling()
{
dynamic obj = new SomeWrapperClass(); // This extends DynamicObject
obj.OnMyEvent += (Action)(() => Console.WriteLine("DO something!"));
obj.Test();
}
}
Zunächst einmal, vielen Dank für den Hinweis auf nur die IL (es oder eine eher High-Level-Darstellung) zu sehen. Was ich sehr interessant finde, ist, wie es den Rückgabewert von GetMember behandelt. Könnte ich nicht einfach ein statisches "Mock" -Ereignis verwenden, um von TryGetMember für alle meine Ereignisse zurückzukehren, und dann die tatsächliche Bindung in TryInvokeMember durchführen? (für add_XYZEvent)? – Storm
Das würde ich versuchen, ja. Ich habe keine Ahnung, ob es gut funktionieren würde, aber wenn du es herausgefunden hast, teile es bitte mit. :) – dahlbyk