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); });
4

3 に答える 3

16

(etc) は(より具体的なものではなく) 取るだけなので、作成するデリゲートのタイプをコンパイラに伝える必要があります。InvokeDelegate

最大の聴衆に適用するにMethodInvokerは、便利な委任型です

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

ただし... BackgroundWorker.ProgressChangedUIスレッドで自動的に起動するため、これは必要ありません。

于 2009-06-09T08:11:04.273 に答える
7

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

したがって、derive-from-Delegateタイプへの明示的なキャストの必要性。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!"); });
  }

これについては、イアン・グリフィスによるこのページで詳しく説明しています。(Notesヘッダーの後のパラグラフを参照してください)

于 2009-06-09T07:57:30.603 に答える
5

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

だからあなたは次のようなものを持っているでしょう

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

また

BeginInvoke((Predicate)delegate(object yourParameter){return YourCode.IsTheParameterSomething(yourParameter)});

HTH

于 2009-12-08T16:16:49.957 に答える