在写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,而非发生了重载操作。

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

如何重载delegate的更多相关文章

  1. Unity[C#] Reflection Use

      Reflection Reflection是C#程序员的一个最有力工具 最常用的例子来说明反射的用处是一个插件系统.假设你正在创建一个 接受用户创建 的扩展程序,有没有办法预先知道哪些方法这个扩展 ...

  2. 窥探Swift之协议(Protocol)和委托代理(Delegate)回调的使用

    协议与委托代理回调在之前的博客中也是经常提到和用到的在<Objective-C中的委托(代理)模式>和<iOS开发之窥探UICollectionViewController(四) - ...

  3. UIScrollView的delegate方法妙用之让UICollectionView滑动到某个你想要的位置

    一个UICollectionView有好多个cell,滑动一下,谁也不知道会停留在哪个cell,滑的快一点,就会多滑一段距离,反之则会滑的比较近,这正是UIScrollview用户体验好的地方. 如果 ...

  4. 01-C#入门(函数重载、委托)

    函数的重载 相对委托,是比较好理解的. 涉及一个概念:函数签名.函数签名包括函数的名称和参数,而函数重载:就是使用相同的名称和不同的参数(参数类型.传递方式[传值或引用])来实现的.而不能声明相同的函 ...

  5. C#一元运算重载的深入理解

    using System; using System.Diagnostics; using System.Text; using System.Collections; using System.Co ...

  6. C#的委托和事件(delegate)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Dele ...

  7. CLR via C#(12)-委托Delegate

    本来按照进度应该学习事件了,可总觉得应该委托在前,事件在后,才好理解. 委托是一个类,它提供了回调函数机制,而且是类型安全的.使用委托可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数 ...

  8. Android的Proxy/Delegate Application框架 (主要介绍插件化开发)

    1. 插件化的原理 是 Java ClassLoader 的原理:Java ClassLoader基础 常用的其他解决方法还包括:Google Multidex,用 H5 代替部分逻辑,删无用代码,买 ...

  9. Delegate(委托与事件)

    Delegate可以当它是一个占位符,比如你在写代码的时候并不知道你将要处理的是什么.你只需要知道你将要引入的参数类型和输出类型是什么并定义它即可.这就是书本上所传达的方法签名必须相同的意思. 系统自 ...

随机推荐

  1. 帮助对@Repository注解的理解

    定义(来自Martin Fowler的<企业应用架构模式>): Mediates between the domain and data mapping layers using a co ...

  2. asp.net mvc 自定义身份验证 2

    控制成员角色 [Authorize(Rroles="Administator,SuperAdmin")] public class StoreManagerController:C ...

  3. [转]centos6.6 rpm安装与管理

    centos6.6 rpm安装与管理 原文地址:http://www.centoscn.com/CentOS/2015/0414/5182.html   rpm包管理:安装.升级.卸载.查询.检验 安 ...

  4. javascript面向对象(三)

    主要内容: 利用原型链的方式实现继承: 原型继承的特点:即继承了父类的模板,也继承了父类的原型对象. 类继承:只继承模板(借用构造函数的方式继承). 利用call.apply方法实现: 混合继承: 扩 ...

  5. 一个CURL

    CURL curl是利用url语法规则来传输文件,数据的工具,主要实现和服务器中网页,资源传输的工具.这里有一个关于感冒还没好的段子. 1.去phpini开启curl扩展,重启阿帕奇或者配置环境变量或 ...

  6. 自动化-Appium

    1.手把手教你 Android 标准 APP 的四大自动化测试法宝:https://testerhome.com/topics/5846 2.中文 Appium API 文档:https://test ...

  7. CSS 部件

    1.导航菜单: [荐]抽屉式菜单 jQuery.mmenu jQuery.mmenu 实现了类似手机上经常使用的抽屉式菜单,效果很好.http://mmenu.frebsite.nl/ 2.jQuer ...

  8. easyui tree onloadsuccess事件的心得

    在onloadSuccess事件中不能apeed新节点,否则又会触发noloadsuccess事件,形成死循环. 公司电话:028-87657875           13060063607 淘宝店 ...

  9. ORA-12543: TNS:destination host unreachable

    在连接Oracle数据库时,如果使用Tnsnames.ora中配置的数据源名称有时会报 ORA-12543: TNS:destination host unreachable 异常,比如:在Tnsna ...

  10. SQLiteHelper

    /** * 实现对表的创建.更新.变更列名操作 * * */ public class SQLiteHelper extends SQLiteOpenHelper { public static fi ...