2016-04-08 16 views
0

私はデリゲートと一緒に遊んでいますが、私は基本的な何かを明確に把握していません。基本的なデリゲートの例で「オブジェクトがターゲットタイプと一致しません」

私は次のことを持っている

:上記の例で

class Test 
{ 
    delegate bool Foo(); 

    public void Run() 
    { 
     Delegate foo = new Foo((delegate() { return true; })); 
     bool result = (bool)foo.Method.Invoke(foo, null); 
    } 
} 

Test test = new Test(); 
test.Run(); 

私は例外が発生した:「オブジェクトは、ターゲット・タイプと一致していません。」

次作品大丈夫、しかし:私の最初の実装で間違って何

class Test 
{ 
    delegate bool Foo(); 

    public void Run() 
    { 
     Foo foo = new Foo((delegate() { return true; })); 
     bool result = foo.Invoke(); 
    } 
} 

Test test = new Test(); 
test.Run(); 

?パラメータを指定せずにfooのメソッドを呼び出すべきではありませんか?これは後者のコードと同じように見えます。

答えて

3

まず、デリゲートを使用する理由をすべて迂回しています。目安として、は触れないでくださいMethod

MethodInfo.Invokeの最初の引数はthisです。これはnullなどとすることができます(デリゲートがインスタンスメソッドを表すときにクロージャーや実際のオブジェクトインスタンスなど)が、となることはありません。はデリゲートインスタンスになります。意味がありません。

あなたのケースでは、実際にはクロージャインスタンスです。しかし、デリゲートの外にあるクロージャには言及していません。コンパイラによってシーンの後ろに作成されています。したがって、呼び出しを行う唯一の適切な方法(MethodInfoを使用)はfoo.Method.Invoke(foo.Target, null);になります。もちろん、これは完全に冗長です。ちょうど人間と同じようにfoo();を使用してください。

同様に、古いデリゲート構文を使用しないでください。そうすることにはほとんど意味がありません。簡単です

Func<bool> foo =() => true; 
Console.WriteLine(foo()); 

は正常に動作します。本当に必要な場合は自分のデリゲートをFunc<bool>に置き換えることができますが、カスタムデリゲートを使用することは今日ではあまり役に立ちません。

+0

ありがとうございました。このサンプルコードは、はるかに大きなコードベースから抽出されているため、コード自体が奇妙に見えます。なぜ例外がスローされているのか理解しようとするが、最初に議員の仕組みを学ぶ必要がある。 –

+0

@SeanAndersonデリゲートはとてもシンプルです。デリゲートは 'Target'だけでなく、' Method'を呼び出すだけです。彼らは一種のインタフェースのようなものです:)あなたが反射的なジャンボをやっていない限り、あなたはどちらでも気にしません - 単に 'Invoke'(またはより良い、'(...) ')、あなた大丈夫です。もし誰かが 'Delegate.Method.Invoke'の代わりに' Delegate.Method.Invoke'を使用していたら、それを見つけてなぜか尋ねます。場合によっては野球のバットを持って来てください。 – Luaan

+0

コードは実際には反射的なジャンボジャンボをやっています。 Reflectionは、私たちが反映しようとしているDLLへの古い参照のために失敗しているように見えますが、それを100%自信がないので、まず問題を少し煮詰めようとしています。私は詳細な対応に感謝します。 –

関連する問題