从异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }说开去

从异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }说开去。

 查看如下代码:

          this.Invoke(delegate
                {
                    MessageBox.Show("t4");
                });

熟悉winform的开发者都知道,this是一个窗体的实例,故不做另外解释。该代码的运行,就会导致异常:{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }。

 其实,要从错误的提示信息来看,这个匿名方法写的是一点问题都没有的。问题的关键是invoke这个函数的参数,我们查看其原型为:
 public object Invoke(Delegate method)
 也就说,它所接受的是一个Delegate,那么,任何一个派生自Delegate的实例,都是可被接受的。我们知道,类似ThreadStart,MethodInvoker都派生自Delegate,那么编译器在转化这个匿名函数的时候,就不知道要将这个匿名函数转为ThreadStart还是MethodInvoker,于是报错。(代表一个委托函数的,还有ParameterizedThreadStart、WaitCallback、AsyncCallback等,只不过他们都是带有参数的。)
 正确的语法应该如下:

     this.Invoke(new MethodInvoker(delegate { MessageBox.Show("t3"); }));
        或者
     this.Invoke((ThreadStart)delegate
                {
                    MessageBox.Show("t4");
                });

这样,编译器就知道要将匿名函数转化为哪个参数了。
题外话:注意这里,无论是new还是转型,都是一样的。

 现将各类语法总结如下:

复制代码
private void button1_Click(object sender, EventArgs e)
        {
            //将delegate转为ThreadStart
            Thread t1 = new Thread((ThreadStart)delegate { MessageBox.Show("t1"); }); 
            t1.Start();
            //将delegate转为ThreadStart的第二种写法
            Thread t2 = new Thread(new ThreadStart(delegate() { MessageBox.Show("t2"); }));
            t2.Start();
            //将delegate转为MethodInvoker
            this.Invoke(new MethodInvoker(delegate { MessageBox.Show("t3"); }));
            //将delegate转为ThreadStart
            this.Invoke((ThreadStart)delegate
                {
                    MessageBox.Show("t4");
                });
            //将delegate转为WaitCallback
            ThreadPool.QueueUserWorkItem((WaitCallback)delegate
            {
                MessageBox.Show("t5");
            });
            //默认将delegate转为WaitCallback,因为QueueUserWorkItem只接受WaitCallback参数
            ThreadPool.QueueUserWorkItem(delegate
                {
                    MessageBox.Show("t5");
                });
            WaitCallback wc = new WaitCallback(this.DoSomethingWithState);
            ThreadPool.QueueUserWorkItem(wc, "i am state.");
        }

        void DoSomethingWithState(Object c)
        {
            MessageBox.Show("t6" + c.ToString());
        }
复制代码

最后,附上几个Delegate的原型:

public delegate void ThreadStart();
 public delegate void MethodInvoker();
 public delegate void WaitCallback(object state);
 public delegate void ParameterizedThreadStart(object obj);
 public delegate void AsyncCallback(IAsyncResult ar);

参考链接:

1、从异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }说开去

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

posted @   rainbow70626  阅读(246)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
历史上的今天:
2017-12-20 C/C++结构体字节对齐详解
2017-12-20 Sizeof与Strlen的区别与联系
2017-12-20 MFC各个控件之间运用SendMessage()传送CString和char[]字符串,以及int类型数据
2016-12-20 JAVA IDE IntelliJ IDEA使用简介(一)—之界面元素
2016-12-20 ASP.NET MVC的运行机制--url的全局分析
点击右上角即可分享
微信分享提示