C# 匿名方法和委托
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/968709/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Anonymous methods and delegates
提问by Mez
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); });
采纳答案by Gishu
The Delegate class is the base class for delegate types. However, only the system and compilers can derive explicitly from the Delegate class or from the MulticastDelegate class. It is also not permissible to derive a new type from a delegate type. The Delegate class is not considered a delegate type; it is a class used to derive delegate types. Source -- MSDN
Delegate 类是委托类型的基类。但是,只有系统和编译器可以显式地从 Delegate 类或 MulticastDelegate 类派生。也不允许从委托类型派生新类型。Delegate 类不被视为委托类型;它是一个用于派生委托类型的类。来源——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. That's just too much flexibility.
因此需要显式转换为派生自委托类型。当您为 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!"); });
}
More on this at this page by Ian Griffith. (See the paras after the Notes header)
伊恩·格里菲斯 (Ian Griffith)在此页面上提供了更多相关信息。(见注释标题后的段落)
回答by Marc Gravell
You need to tell the compiler what typeof delegate to create, since Invoke
(etc) just take Delegate
(rather than something more specific).
您需要告诉编译器要创建什么类型的委托,因为Invoke
(等)只是采用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 线程上自动触发 - 所以你甚至不需要这个。
回答by EightyOne Unite
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; you just don't need to create a custom delegate type for simple things like that.
大多数情况下,您在处理这些情况下的无参数委托或谓词。对此进行排序的最简单方法是将匿名方法直接转换为其中一个Action
或Predicate
分别;您只是不需要为这样的简单事情创建自定义委托类型。
So you'll have something like
所以你会有类似的东西
BeginInvoke((Action)delegate(){YourCode.DoSomething();});
or
或者
BeginInvoke((Predicate)delegate(object yourParameter){return YourCode.IsTheParameterSomething(yourParameter)});
HTH
HTH