zoukankan      html  css  js  c++  java
  • 关于委托:异常{ 无法将 匿名方法 转换为类型“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);

  • 相关阅读:
    Jmeter中ftp测试下载默认路径及文件
    python中http请求方法库汇总
    快速解决mysql Lost connection to MySQL server at 'reading initial communication packet及can't connect to mysql server on 'localhost'
    Python GUI--Tkinter实践
    Shell脚步之监控iostat数据
    C++二进制字符串转十六进制字符串 十六进制字符串转二进制字符串
    C++调用openssl实现DES加密解密cbc模式 zeropadding填充方式 pkcs5padding填充方式 pkcs7padding填充方式
    DES加解密 cbc模式 的简单讲解 && C++用openssl库来实现的注意事项
    C++ 使用openssl库实现 DES 加密——CBC模式 && RSA加密——公加私解——私加公解
    C++ 解析json串
  • 原文地址:https://www.cnblogs.com/liulaocai2/p/4383494.html
Copyright © 2011-2022 走看看