Test2とTest3が正常に動作している間、Test1は "System.ArgumentException:メソッドの引数の長さの不一致"を生成します。反射を使ってイベントに登録する必要があります。単純なメソッドを使用するとすべてが機能しますが、lambdaに入ると、期待どおりに機能しなくなります。メソッドとしてlambdaをDelegate.CreateDelegateが "メソッド引数の長さの不一致"例外を生成する
すべてのlambdasのデバッグでは、「Void <> m__0(Int32)」というイベントは正しいタイプであり、「eventInfo.EventHandlerType」と同じです。
なぜ失敗するのですか?または、回避策を講じる方法は?
Test1のようにlambdaによって作成されたメソッドに引数を追加しますか?
::ここに完全なコード:
public class A
{
public void Test1()
{
var str = "aa";
B.Subscribe(typeof(C), "myEvent", (int a) => { var any = str; }, null);
}
public void Test2()
{
B.Subscribe(typeof(C), "myEvent", (int a) => { var any = a; }, null);
}
public void Test3()
{
B.Subscribe<int>(typeof(C), "myEvent", callback, this);
}
public void callback(int a) { }
}
public static class B
{
public static void Subscribe<T>(Type type, string eventName, Action<T> callback, object target)
{
var eventInfo = type.GetEvent(eventName, BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
var handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, target, callback.Method);
eventInfo.AddEventHandler(null, handler);
}
}
public sealed class C
{
public static event Action<int> myEvent;
}
EDIT:
どうやらそれはモノのバグです。デリゲートを取得するためのGetInvocationList()[0]は上の例の問題を修正します。
ただし、イベントを購読すると、 "System.InvalidCastException:ソースタイプから宛先タイプにキャストできません。"イベントはタイプアクションのが、カスタムデリゲートでない場合:(クラス「C」はそのようであれば、それはクラス「C」は、上記のようなものであるならば、それは罰金渡し、スロー)
public sealed class C
{
public static event MyDel myEvent;
public delegate void MyDel(int a);
}
それは別の問題ですか?編集#2、イベントはMyDel
タイプを想定していますが、アクションInt32を取得します。 Action<T>
からMyDel以上に変換するには、どのタイプのイベントが可能かわからないので、eventInfo.EventHandlerType
に変換するにはどうすればよいですか。
MS .NETでうまく動作します。モノ問題があるかもしれませんか? – VinSmile
モノのバグにバグがあるようです。これをチェックするhttp://lists.ximian.com/pipermail/mono-bugs/2010- December/126824.html –
'Method'の代わりに' GetInvocationList() '(返されるリストの最初の要素)を使うとどうなりますか? ?後者はうまくいくはずですが、@ VinSmileが言っているように、Monoの問題かもしれません。 –