在写delegate的时候遇到一个问题,在已有一个不带参数的delegate基础上,试图再增加一个带参数的delegate,结果VS报了“already contains a definition for ‘InvokeDelegate’”这样的错误。

第一眼看上去,代码似乎没什么问题:

 private delegate void InvokeDelegate();
private delegate void InvokeDelegate(string param);

其实这是把delegate等同于了method,所以才会认为使用method的重载方式也可以重载delegate。

翻过《CLR via C#》这本书,或者直接用ILDASM工具查看就会明白,delegate在编译时会被编译器翻译成一个继承MulticastDelegate的类。

因此,delegate真实的代码应该是这样的:

 private sealed class InvokeDelegate : MulticastDelegate
{
public InvokeDelegate(Object object, IntPtr method);
public virtual void Invoke();
public IAsyncResult BeginInvoke(AsyncCallback callback, Object object);
public virtual void EndInvoke(IAsyncResult result);
} private sealed class InvokeDelegate : MulticastDelegate
{
public InvokeDelegate(Object object, IntPtr method);
public virtual void Invoke();
public IAsyncResult BeginInvoke(string param, AsyncCallback callback, Object object);
public virtual void EndInvoke(IAsyncResult result);
}

这样就不难看出,之前的写法会生成同样名称的两个类,这个当然是不被允许的。而两者唯一的区别就在于BeginInvoke方法中的参数。

那么是否就没有办法重载delegate了呢?

再看看.NET Framework中已有的Action委托。Action,Action,Action……各种形式都有。看一下它们的语法。

Action委托:public delegate void Action()
Action委托:public delegate void Action(T obj)
Action委托:public delegate void Action(T1 arg1, T2 arg2)

显然使用泛型的方式可以实现重载delegate的需求。

如果把“private delegate void InvokeDelegate(string param);”改成“private delegate void InvokeDelegate<in T>(T param);”,会生成以下的新类。

 private sealed class InvokeDelegate<T> : MulticastDelegate
{
public InvokeDelegate(Object object, IntPtr method);
public virtual void Invoke(T param);
public IAsyncResult BeginInvoke(T param, AsyncCallback callback, Object object);
public virtual void EndInvoke(IAsyncResult result);
}

这种写法便不会与第一个delegate发生冲突了。

不过最后需要补充的是,重载delegate这样的说法并不正确,其实只是定义了不同类型的delegate,而非发生了重载操作。

原文同步发布于我的个人博客

最新文章

  1. LINQ教程
  2. 【转】单表60亿记录等大数据场景的MySQL优化和运维之道 | 高可用架构
  3. 让HTML页面缩放适应移动客户端尺寸
  4. JAVA数组的典型操作
  5. &quot;Java 反序列化&quot;过程远程命令执行漏洞
  6. Linq to Entities下存储过程的使用方法
  7. Windows平台配置免安装的MySQL
  8. 如何破解excel宏的密码
  9. 线性表 - 从零开始实现by C++
  10. Java 内存分析图
  11. 为什么 HTTP 有时候比 HTTPS 好?
  12. ACM入门:第s名的小红
  13. 从壹开始微服务 [ DDD ] 之三 ║ 简单说说:领域、子域、限界上下文
  14. HTML之超链接
  15. API &amp; Web API
  16. (PMP)第1章-----引论
  17. 五、Oracle 分组查询、视图
  18. Identity(三)
  19. 1. Mysql数据库的安装
  20. Thunder团队Alpha周贡献分规则及贡献分分配结果

热门文章

  1. Ubuntu15下mysql5.6.25解决不支持中文的办法
  2. tomcat(三)--基本安装配置
  3. Unix权限管理
  4. EAA脚本语言0.2
  5. Paxos算法分析
  6. 通过ssh连接github
  7. 未定义标识符string
  8. 数字与字母 随机数小demo
  9. 用Backbone.js教程系列的链接
  10. 面向对象程序设计 第二次作业&lt;1&gt;