C#匿名方法与Delegate类型转换错误
问题描述
C#2.0出现了匿名方法, 这在一定程度上节省了我们维护代码上下文的精力, 也不需要思考为某个方法取什么名字比较合适. 在FCL的一些方法中要求传入一个Delegate类型的参数, 比如Control.Invoke或者Control.BeginInvoke方法:
1 2 | public object Invoke(Delegate method); public IAsyncResult BeginInvoke(Delegate method); |
在这种情况下, 如果不使用匿名方法, 则需要在代码的上面先声明一个delegate void DoSomething()方法, 然后可以在Invoke方法中再用lambda表达式或者委托实现DoSomething().
1 2 3 4 5 6 7 8 9 | delegate void DoSomething(); private void App() { XXControl.Invoke( new DoSomething(() => { //DoSomething的具体操作 })); } |
这样做可以是可以, 但使用匿名方法则更好, 最起码看上去更简洁.
1 2 3 4 5 6 7 | private void App() { XXControl.Invoke( delegate { //DoSomething的具体操作 }); } |
上面的代码会在编译的时候出错: Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type. 方法要求参数的是一个委托(delegate)类型, 而现在传递的只是一个匿名方法. 产生这个错误最根本的原因是编译器在处理匿名方法的时候, 没法推断出这个委托的方法返回的是什么类型, 也就不知道返回一个什么样的委托.
解决方法
要解决上面这个问题, 从根本上来说就是指定这个匿名方法将会返回什么类型的委托, 有几种方法:
1. 使用MethodInvoke或者Action
1 2 3 4 5 6 7 | private void App() { XXControl.Invoke((MethodInvoker) delegate () { //DoSomething的具体操作 }); } |
1 2 3 4 5 6 7 | private void App() { XXControl.Invoke((Action) delegate () { //DoSomething的具体操作 }); } |
MethodInvoke和Action都是方法返回类型为空的委托.
2. 可以给Control定义一个Invoke的扩展方法
1 2 3 4 | public static void Invoke( this Control control, Action action) { control.Invoke((Delegate)action); } |
调用的时候则可以这样调用:
1 2 3 4 | //使用委托 XXControl.Invoke( delegate { //DoSomething here}); //使用lambda表达式 XXControl.Invoke(()=>{ //DoSomething here}); |
参考
1. http://stackoverflow.com/questions/253138/anonymous-method-in-invoke-call
2. http://staceyw1.wordpress.com/2007/12/22/they-are-anonymous-methods-not-anonymous-delegates/
作者:Create Chen
出处:http://technology.cnblogs.com
说明:文章为作者平时里的思考和练习,可能有不当之处,请博客园的园友们多提宝贵意见。
本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库