博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于委托:异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }...
阅读量:5056 次
发布时间:2019-06-12

本文共 2023 字,大约阅读时间需要 6 分钟。

 

异常{ 无法将 匿名方法 转换为类型“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);

转载于:https://www.cnblogs.com/kakaliush/archive/2011/12/16/2289599.html

你可能感兴趣的文章
Java中的多线程
查看>>
32. Longest Valid Parentheses
查看>>
定制ListView的界面(让列表中不仅有文字还有图片fruitImage.setImageResource(fruit.getImageId());)...
查看>>
PHP实体层基础类
查看>>
SQL CODE
查看>>
2019春总结作业
查看>>
前端代码规范
查看>>
循环语句
查看>>
iOS----------YYModel
查看>>
Javascript初步
查看>>
比起 Windows,怎样解读 Linux 的文件系统与目录结构?
查看>>
文件修改
查看>>
Can't create handler inside thread that has not called Looper.prepare()
查看>>
图像的双缓存技术
查看>>
微信小程序template模板与component组件的区别及使用方法
查看>>
android开发 多线程
查看>>
我害怕了吗?
查看>>
使用openpyxl 操作excel的基础
查看>>
http etag
查看>>
通过机构查询该机构下,以及下级机构的人员 id
查看>>