无法将匿名方法转换为类型“System.Delegate”,因为它不是委托类型

问题描述 投票:0回答:2

我想在 WPF 应用程序的主线程上执行此代码并收到错误,我无法弄清楚出了什么问题:

private void AddLog(string logItem)
{
    this.Dispatcher.BeginInvoke(
        delegate()
            {
                this.Log.Add(new KeyValuePair<string, string>(DateTime.Now.ToLongTimeString(), logItem));
            });
}
c# wpf
2个回答
25
投票

匿名函数(lambda 表达式和匿名方法)必须转换为特定委托类型,而

Dispatcher.BeginInvoke
只需要
Delegate
。有两种选择...

  1. 仍然使用现有的

    BeginInvoke
    调用,但指定委托类型。这里有多种方法,但我通常将匿名函数提取到前面的语句中:

    Action action = delegate() { 
         this.Log.Add(...);
    };
    Dispatcher.BeginInvoke(action);
    
  2. Dispatcher
    上编写一个扩展方法,该方法采用
    Action
    而不是
    Delegate

    public static void BeginInvokeAction(this Dispatcher dispatcher,
                                         Action action) 
    {
        Dispatcher.BeginInvoke(action);
    }
    

    然后就可以通过隐式转换来调用扩展方法了

    this.Dispatcher.BeginInvokeAction(
            delegate()
            {
                this.Log.Add(...);
            });
    

一般情况下,我还鼓励您使用 lambda 表达式而不是匿名方法:

Dispatcher.BeginInvokeAction(() => this.Log.Add(...));

编辑:如评论中所述,

Dispatcher.BeginInvoke
在.NET 4.5中获得了重载,它直接采用
Action
,因此在这种情况下您不需要扩展方法。


4
投票

您还可以使用 MethodInvoker 来实现此目的:

private void AddLog(string logItem)
        {
            this.Dispatcher.BeginInvoke((MethodInvoker) delegate
            {
                this.Log.Add(new KeyValuePair<string, string>(DateTime.Now.ToLongTimeString(), logItem));
            });
        }
© www.soinside.com 2019 - 2024. All rights reserved.