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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15935867/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:33:22  来源:igfitidea点击:

Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type

c#wpf

提问by katit

I want to execute this code on main thread in WPF app and getting error I can't figure out what is wrong:

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

private void AddLog(string logItem)
        {

            this.Dispatcher.BeginInvoke(
                delegate()
                    {
                        this.Log.Add(new KeyValuePair<string, string>(DateTime.Now.ToLongTimeString(), logItem));

                    });
        }

回答by Jon Skeet

Anonymous functions (lambda expressions and anonymous methods) have to be converted to a specificdelegate type, whereas Dispatcher.BeginInvokejust takes Delegate. There are two options for this...

匿名函数(lambda 表达式和匿名方法)必须转换为特定的委托类型,而Dispatcher.BeginInvoke只需将Delegate. 对此有两种选择...

  1. Still use the existing BeginInvokecall, but specify the delegate type. There are various approaches here, but I generally extract the anonymous function to a previous statement:

    Action action = delegate() { 
         this.Log.Add(...);
    };
    Dispatcher.BeginInvoke(action);
    
  2. Write an extension method on Dispatcherwhich takes Actioninstead of Delegate:

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

    Then you can call the extension method with the implicit conversion

    this.Dispatcher.BeginInvokeAction(
            delegate()
            {
                this.Log.Add(...);
            });
    
  1. 仍然使用现有BeginInvoke调用,但指定委托类型。这里有多种方法,但我一般将匿名函数提取到前面的语句中:

    Action action = delegate() { 
         this.Log.Add(...);
    };
    Dispatcher.BeginInvoke(action);
    
  2. 编写一个扩展方法,用DispatcherAction代替Delegate

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

    然后你可以用隐式转换调用扩展方法

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

I'd also encourage you to use lambda expressions instead of anonymous methods, in general:

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

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

EDIT: As noted in comments, Dispatcher.BeginInvokegained an overload in .NET 4.5 which takes an Actiondirectly, so you don't need the extension method in that case.

编辑:如评论中所述,Dispatcher.BeginInvoke在 .NET 4.5 中获得了一个Action直接采用 的重载,因此在这种情况下您不需要扩展方法。

回答by Pinetwig

You can also use MethodInvokerfor this:

您还可以为此使用MethodInvoker

private void AddLog(string logItem)
        {
            this.Dispatcher.BeginInvoke((MethodInvoker) delegate
            {
                this.Log.Add(new KeyValuePair<string, string>(DateTime.Now.ToLongTimeString(), logItem));
            });
        }