如何重载delegate

在尝试重载已有不带参数的委托时遇到编译错误,因为委托在编译时会被转换为继承自MulticastDelegate的类。通过查看《CLR via C#》或IL代码,发现不能直接通过方法签名重载。但可以通过使用泛型来定义不同的委托类型,如Action的多种形式。将委托定义为`private delegate void InvokeDelegate<in T>(T param);`即可避免冲突,实现类似重载的效果,但实际上并非真正的重载操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值