2009-06-09 13 views
14

BeginInvokeメソッドが匿名メソッドを受け入れない理由を理解しようとします。匿名のメソッドと代理人

void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    if (InvokeRequired) 
    { 
     //Won't compile 
     BeginInvoke(delegate(object sender, ProgressChangedEventArgs e) 
     { bgWorker_ProgressChanged(sender, e); }); 
    } 

    progressBar1.Increment(e.ProgressPercentage); 
} 

それは私がデリゲートに匿名メソッドをキャストするとき、それは動作しませんしながら、System.Delegate 『『を』匿名メソッド「から変換することはできません』と言われますか?

BeginInvoke((progressDelegate)delegate { bgWorker_ProgressChanged(sender, e); }); 
+1

があるでしょう、あまりにも、この質問を見てください:http://stackoverflow.com/questions/253138 /匿名メソッドインコールコール – tanascius

答えて

7

委任クラスは、委任タイプの基本クラスです。ただし、システムとコンパイラのみが、DelegateクラスまたはMulticastDelegateクラスから明示的に派生することができます。デリゲート型から新しい型を派生させることも許されません。 Delegateクラスはデリゲート型とはみなされません;デリゲート型を派生させるために使用されるクラスです。 ソース - MSDN

したがって、委任型から継承型への明示的キャストの必要性。 System.Delegate型のパラメータに匿名メソッドを渡すと、この特定のコンパイラエラーが発生します。幸いにもこれはまれなシナリオです。それはあまりにも多くの柔軟性です。

delegate void MyDelegate(); 

    static void DoSomething_Flexible(Delegate d) 
    { d.DynamicInvoke();  } 
    static void DoSomething_Usable(MyDelegate d) 
    { d();  } 
    static void Main(string[] args) 
    { 
    // requires explicit cast else compile error Error "Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type  
    DoSomething_Flexible((MyDelegate) delegate { Console.WriteLine("Flexible is here!"); }); 

    // Parameter Type is a .NET Delegate, no explicit cast needed here. 
    DoSomething_Usable(delegate { Console.WriteLine("Usable is here!"); }); 
    } 

さらに詳しい説明はthis page by Ian Griffithです。 Invoke(など)だけで(より具体的なものではなく)Delegate取るために、あなたがデリゲートのを作成するために、どのようなタイプコンパイラに指示する必要があり

+0

素晴らしい答えですが、私はSomeControl.BeginInvoke(Delegateメソッド、paramオブジェクト[] args)を* rare *と記述することはできません。 –

+0

@PeterWone - :)私はUIのスレッドの親和性を処理するBackgroundWorkerインスタンスを使用することをお勧めします。この方法で書かれた既存のサードパーティメソッドについては何もできません。小さな(アクション)キャストでマークする必要があります – Gishu

16

(注ヘッダの後にパラグラフを参照してください)。最大の観客に適用する

MethodInvoker

BeginInvoke((MethodInvoker) delegate(...) {...}); 

便利なデリゲート型であるしかし...自動的にUIスレッド上BackgroundWorker.ProgressChanged火災 - ので、あなたも、これを必要としません。

5

ほとんどの場合、これらのケースでは、パラメータのないデリゲートまたは述語を扱っています。これをソートする最も簡単な方法は、匿名メソッドをそれぞれActionまたはPredicateに直接キャストすることです。そのような単純なもののためのカスタムデリゲート型を作成する必要はありません。

ですから、

BeginInvoke((Action)delegate(){YourCode.DoSomething();}); 

または

​​

のようなものHTH

関連する問題