リフレクターは、この1つにあなたの友人です。
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);
}
あなたは(あなたがデフォルトDynamicObject
実装に傾くことができ、その場合には)OnMyEvent
のための本当のイベントを使用できない場合、あなた」:2番目の行のために生成されたコードは(約)は、このようになりますAddAssign
がマルチキャストデリゲートのようなものを返すようなものを返す必要があります。
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();
}
}
最初に、生成したILをちょうど見ることについてのヒントに感謝します(よくまたはかなり高いレベルの表現)。かなり興味深いのは、GetMemberの戻り値を処理する方法です。 TryGetMemberから返されたすべてのイベントに対して静的な「模擬」イベントを使用してTryInvokeMemberで実際のバインディングを実行するだけではどうですか? (add_XYZEventの場合)? – Storm
それは私が試みることです、はい。私はそれがうまくいくかどうか分かりませんが、もしそれが分かれば分かち合いましょう。 :) – dahlbyk