2009-06-04 16 views
7

私は、DelegateクラスがTargetプロパティを持っていることに気付きました.Draggateクラスはデリゲートメソッドが実行するインスタンスを返すでしょう。この」nullターゲットを使用してインスタンスメソッドへのデリゲートを作成するにはどうすればよいですか?

class A 
{ 
    void Method(int a) {} 

    static void Main(string[] args) 
    { 
     A a = null; 
     Action<int> action = a.Method; 
     PossiblyExecuteDelegate(action); 
    } 
} 

しかし、私はインスタンスメソッドにArgumentExceptionが(委任を取得し、ヌルを持つことはできません:、私のような何かをしたい、それを呼び出すとすると

void PossiblyExecuteDelegate(Action<int> method) 
{ 
    if (method.Target == null) 
    { 
     // delegate instance target is null 
     // do something 
    } 
    else 
    { 
     method(10); 
     // do something else 
    } 
} 

:私はこのような何かをしたいです')私はデリゲートを構築しようとするとき。私ができることは可能なのですか?どうすればいいですか?

+0

なぜこれをやりたいですか? nullのインスタンスがありますか? –

答えて

15

アハ! found it!

あなたが明示的に指定した「この」第一引数暗黙的にデリゲートを使用して、CreateDelegateオーバーロードを使用したオープン・インスタンスのデリゲートを作成することができます正確に過負荷で、

delegate void OpenInstanceDelegate(A instance, int a); 

class A 
{ 
    public void Method(int a) {} 

    static void Main(string[] args) 
    { 
     A a = null; 
     MethodInfo method = typeof(A).GetMethod("Method"); 
     OpenInstanceDelegate action = (OpenInstanceDelegate)Delegate.CreateDelegate(typeof(OpenInstanceDelegate), a, method); 

     PossiblyExecuteDelegate(action); 
    } 
} 
+0

はい、独自のレスポンスを編集したので、これはリフレクションでは可能ですが、標準のコンパイル済み.NETコードでは可能ではありません。あなたの懸念は、人々があなたに代わって宣言した代議員をあなたに渡すことでしょうか? –

1

これを行うには、staticメソッドをPossiblyExecuteDelegate()に渡す必要があります。これにより、nullTargetとなります。

class A 
{ 
    void Method(int a) {} 
    static void Method2(int a) {} 

    static void Main(string[] args) 
    { 
     PossiblyExecuteDelegate(A.Method2); 

     A a = new A(); 

     PossiblyExecuteDelegate(a.Method); 
    } 
} 

編集:それは反射介しないターゲットとインスタンスメソッドにデリゲートを渡すことが可能であるが、標準的なコンパイルされたコードを使用していません。

+0

私は、インスタンスメソッドが呼び出された場合にnullインスタンスで呼び出されるかどうかをテストします。問題は最初にインスタンスを取得することです。私は開いている代議員について何かを読んだことを覚えていますが、私は今もそれを隠すことはできません。 – thecoop

+0

Delegate.CreateDelegateオーバーロードを使用してオープンインスタンスデリゲートを作成することができます) – thecoop

+0

@thecoop:はい、これはリフレクションでは可能だが、コンパイル時に安全なコードではできないことに注意してください。回答が編集されました。 –

0

それはDelegate.CreateDelegateで可能です署名付き:あなたは二番目のパラメータ(ターゲット) のための「ヌル」を指定した場合 CreateDelegate (Type, object, MethodInfo)

あなたは、インスタンスのタイプを指定するデリゲート型、に追加のパラメータを配置する必要があり、かつWHデリゲートを呼び出すと、インスタンスは最初の引数として渡され、その後にメソッドの「実際の」パラメータが渡されます。

class Test 
{ 
    public int AddStrings(string a, string b) 
    { 
     return int.Parse(a) + int.Parse(b); 
    } 

    static void Main() 
    { 
     var test = new Test(); 
     var methodInfo = test.GetType().GetMethod("AddStrings"); 
     // note the first extra parameter of the Func, is the owner type 
     var delegateType = typeof(Func<Test, string, string, int>); 
     var del = Delegate.CreateDelegate(delegateType, null, methodInfo); 

     var result = (int)del.DynamicInvoke(test, "39", "3"); 
    } 
}