我试图理解为什么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); });
答案 0 :(得分:16)
你需要告诉编译器要创建的委托的 type ,因为Invoke
(等)只需要Delegate
(而不是更具体的东西)。
要应用于最大的受众群体,MethodInvoker
是一个方便的委托类型
BeginInvoke((MethodInvoker) delegate(...) {...});
但是...... BackgroundWorker.ProgressChanged
会自动触发UI线程 - 所以你甚至不需要这个。
答案 1 :(得分:7)
Delegate类是委托类型的基类。但是,只有系统和编译器可以从Delegate类或MulticastDelegate类显式派生。也不允许从委托类型派生新类型。 Delegate类不被视为委托类型;它是一个用于派生委托类型的类。 来源 - MSDN
因此需要显式转换为derived-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!"); });
}
有关this page by Ian Griffith的详情。 (参见Notes标题后面的段落)
答案 2 :(得分:5)
大多数情况下,在这些情况下,您要处理无参数委托或谓词。最简单的排序方法是将匿名方法分别直接转换为Action
或Predicate
;您只需要为这样的简单事物创建自定义委托类型。
所以你会有像
这样的东西BeginInvoke((Action)delegate(){YourCode.DoSomething();});
或
BeginInvoke((Predicate)delegate(object yourParameter){return YourCode.IsTheParameterSomething(yourParameter)});
HTH