无法将匿名方法转换为System.Delegate
在WinForm中,不允许非UI线程访问UI,如果非UI线程需要跨线程调用UI控件,通常的解决办法是使用Control类中的Invoke方法,传递给该方法一个委托和委托调用的参数列表(params []object args),任何委托类型都可以,通过委托来访问UI。其内部是,非UI线程把委托送到UI线程中,让UI线程去调用这个委托。
一般一个方法的参数是委托类型,如果使用委托实例,那就还需要额外定义一个和委托签名一致的方法,比较麻烦。而我一般是使用匿名方法,因为匿名方法方便,不需要额外的声明的一个委托类型了,让代码更加简洁。但是这一次使用匿名方法却出现了错误,在编译的时候就没有被通过,我代码如下(code1):
this.Invoke(delegate(string test) {this.Text=test;},"myCall");
编译时错误如下:
无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型
经过仔细思考,发现这样的写法通过编译确实是对的。首先得明白所有的委托类型都是继承System.Delegate,而Invoke方法委托类型就是Delegate,也就是说,任意的委托类型都可以作为该方法的参数。如果我们使用匿名方法,那么CLR就不知道把该匿名方法转为哪种类型的的委托,因此直接传入一个匿名函数是通不过编译的。知道了为什么错误,代码改成下面这样(code2),就能够正确的运行罗。
Action<string> updateUI = (text) => this.Text = text;
this.Invoke(updateUI,"myCall");
// 或者这样,和上面一样,还是传入Action<string>委托实例
this.Invoke(new Action<string>((text) => this.Text = text), "myCall");
在使用委托类型的时候,建议最好采用系统内部定义Action和Func两种委托类型,而且这两种类型还定义了许多个泛型版本,足够满足我们平常的应用啦。
那么在哪种情况下可以直接传入匿名方法作为参数,举个例子,在使用Linq的扩展Where方法的时候,该方法需要传入一个委托,委托的定义为Func<T,bool>,这种情况我们可以直接使用一个匿名方法,代码如下(code3):
list.Where((s) => s.StartsWith("n"));
因此可以知道,当方法的参数是具体的委托类型时,可以使用匿名方法,因为编译器知道应该把该匿名方法转为何种委托类型;而 当方法的参数为委托的基类System.Delegate时,那就需要自己实例化一个具体委托类型实例(委托类型使用.NET内部定义的,如code2),然后传入进去,这样CLR知道就是何种委托类型。
在C#3.0中有了一个叫Lambda的表达式,和匿名方法是一样效果,但是Lambda能够使代码更加紧凑,更加优异,主要是比较容易理解表达式,可读性好,关于Lambda的用法在这里就不做介绍了。上面的code2和code3的匿名方法都是采用的Lambda表达式,是不是看起来更加简洁。
无法将匿名方法转换为System.Delegate的更多相关文章
- 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型:解决方法
http://blog.csdn.net/xiaochongchong1248/archive/2009/11/20/4841193.aspx?1271573283 编程环境要求:VS2008/FX2 ...
- 关于委托:异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }
转自:http://www.cnblogs.com/xiaofei59/archive/2010/11/25/1887285.html 异常{ 无法将 匿名方法 转换为类型“System.Delega ...
- 关于委托:异常{ 无法将 匿名方法 转换为类型“System.Delegate”,因为它不是委托类型 }
异常{ 无法将 匿名方法 转换为类型"System.Delegate",因为它不是委托类型 } 委托实际上是把方法名作为参数,但是若有好多个方法时,就要指明是哪个参数 查看如下代 ...
- 委托delegate 泛型委托action<> 返回值泛型委托Func<> 匿名方法 lambda表达式 的理解
1.使用简单委托 namespace 简单委托 { class Program { //委托方法签名 delegate void MyBookDel(int a); //定义委托 static MyB ...
- C# 从CIL代码了解委托,匿名方法,Lambda 表达式和闭包本质
前言 C# 3.0 引入了 Lambda 表达式,程序员们很快就开始习惯并爱上这种简洁并极具表达力的函数式编程特性. 本着知其然,还要知其所以然的学习态度,笔者不禁想到了几个问题. (1)匿名函数(匿 ...
- 进阶系列(8)——匿名方法与lambda表达式
一 匿名方法的介绍 匿名方法是为了简化委托的实现,方便调用委托方法而出现的,同时,匿名方法也是学好lambda表达式的基础.在委托调用的方法中,如果方法只被调用一次,这个时候我们就没有必要创建 ...
- 匿名方法、Lambda表达和自定义泛型委托以及Func、Action系统泛型委托
1.匿名方法的概念:一个方法没有具体的名称,而只有关键字delegate.方法参数.方法体.这种方法是匿名方法. 匿名方法的好处:将具体方法和委托直接关联在一起,如果我们基于委托只需要一个方法的时候, ...
- C#委托总结-匿名方法&Lambda表达式
1,匿名方法 匿名方法可以在声明委托变量时初始化表达式,语法如下 之前写过这么一段代码: delegate void MyDel(string value); class Program { void ...
- c#委托、泛型委托和匿名方法
题外话:别指望看第一遍书就能记住和掌握什么——请看第二遍.第三遍. 本人女猿一枚,2年工作经验,喜欢钻研,喜欢创新,闲暇之余喜欢写写博客,深知自身能力薄弱,如表达错误.不当之处请园友们多多指出,互相交 ...
随机推荐
- 3D拓扑自动布局之Web Workers篇
2D拓扑的应用在电信网管和电力SCADA领域早已习以为常了,随着OpenGL特别是WebGL技术的普及,3D方式的数据可视化也慢慢从佛殿神堂步入了寻常百姓家,似乎和最近高档会所被整改为普通茶馆是一样的 ...
- IE11之F12 Developer Tools--概述篇
打开Developer Tools的方法: a. 点击F12 b. 在浏览器中选择Tools-->F12 Develooper Tools 打开后图示: 从上图我们可以看到,Developer ...
- C#文件和文件夹输入输出流代码
1.建立一个文本文件 public class FileClass { public static void Main() { WriteToFile(); } static void WriteTo ...
- HTML页面放大镜效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Android 提供的一系列辅助系统开发工具
除了软件本身的代码之外,Android 还提供了一系列工具来辅助系统开发,这些主要的工具包括: aapt(AndroidAssetPackagingTool):用于建立zip兼容的包(zip.jar. ...
- JavaScript基础10——node对象
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- swift学习笔记之-构造过程
//构造过程 import UIKit /* 构造过程(Initialization): 1.构造过程是使用类.结构体或枚举类型的一个实例的准备过程.在新实例可用前必须执行这个过程,具体操作包括设置实 ...
- 浅谈ES6中的Proxy
Proxy是一个很有趣的对象,它能够修改某些操作的默认行为,等同于在语言层面做出修改,属于一种‘元编程’,即对编程语言进行编程. Proxy其实很好理解,就是在目标对象之前架设一层拦截,外界的访问都得 ...
- C#中的Mutex对象认识
我们知道,有些应用程序可以重复打开,有些只能打开一个,我以前写的程序为了防止用户打开多个程序,都是去遍历Process 查找进程的方式,现在看起来真是不专业,今天看大神的破解分析文章时,认识了mute ...
- MYSQL使用正则表达式过滤数据
一.正则与LIKE的区别 Mysql的正则表达式仅仅使SQL语言的一个子集,可以匹配基本的字符.字符串.例如:select * from wp_posts where post_name REGEXP ...