简体   繁体   English

匿名方法和代理

[英]Anonymous methods and delegates

I try to understand why a BeginInvoke method won't accept an anonymous method. 我试图理解为什么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);
}

It tells me 'cannot convert from 'anonymous method' to 'System.Delegate' while when I cast the anonymous method to a delegate it does work ? 它告诉我'无法从'匿名方法'转换为'System.Delegate',而当我将匿名方法转换为委托时,它确实有效吗?

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

You need to tell the compiler what type of delegate to create, since Invoke (etc) just take Delegate (rather than something more specific). 你需要告诉编译器要创建什么类型的委托,因为Invoke (etc)只需要Delegate (而不是更具体的东西)。

To apply to the largest audience, MethodInvoker is a handy delegate type 要应用于最大的受众, MethodInvoker是一个方便的委托类型

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

However... BackgroundWorker.ProgressChanged fires on the UI thread automatically - so you don't even need this. 但是...... BackgroundWorker.ProgressChanged会自动触发UI线程 - 所以你甚至不需要这样。

The Delegate class is the base class for delegate types. Delegate类是委托类型的基类。 However, only the system and compilers can derive explicitly from the Delegate class or from the MulticastDelegate class. 但是,只有系统和编译器可以从Delegate类或MulticastDelegate类显式派生。 It is also not permissible to derive a new type from a delegate type. 也不允许从委托类型派生新类型。 The Delegate class is not considered a delegate type ; Delegate类不被视为委托类型 ; it is a class used to derive delegate types. 它是一个用于派生委托类型的类。 Source -- MSDN 来源 - MSDN

Hence the need for the explicit cast to a derived-from-Delegate type. 因此需要显式转换为派生自委托类型。 You'd encounter this particular compiler error when you pass an anonymous method for a parameter of System.Delegate type - fortunately this is a rare scenario. 当您为System.Delegate类型的参数传递匿名方法时,您会遇到此特定的编译器错误 - 幸运的是,这是一种罕见的情况。 That's just too much flexibility. 这太灵活了。

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!"); });
  }

More on this at this page by Ian Griffith . Ian Griffith本页的更多内容。 (See the paras after the Notes header) (参见Notes标题后面的段落)

Most of the time you're dealing with either a parameterless delegate or a predicate in these cases. 大多数情况下,在这些情况下,您要处理无参数委托或谓词。 The easiest way of sorting this is by casting your anonymous method directly to either Action or Predicate respectively; 最简单的排序方法是将匿名方法分别直接转换为ActionPredicate ; you just don't need to create a custom delegate type for simple things like that. 您只需要为这样的简单事物创建自定义委托类型。

So you'll have something like 所以你会有类似的东西

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

or 要么

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

HTH HTH

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM