You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中如何实现同签名不同类型委托的引用赋值?

C# 中自定义委托属于强类型定义,即便方法签名完全一致,不同委托类型之间也不存在默认的隐式/显式转换,直接赋值会触发编译错误,可根据实际场景选择以下实现方式:

方案1:统一使用内置泛型委托(推荐,最简洁)

如果可以修改原有委托定义,直接删除冗余的自定义委托,全部使用.NET内置的Action<string>类型即可。该类型的签名为public delegate void Action<in T>(T obj),和你定义的三个委托完全匹配,同类型之间可直接赋值,从根源上规避类型不匹配问题,也是.NET开发的通用规范。

修改后的代码示例:

// 静态类部分修改
public static class StClass
{
    public static Action<string> myD1 { get; set; }
    public static Action<string> myD2 { get; set; }
}

// MyClass部分修改
public class MyClass
{
    public Action<string> myD { get; set; }
   
    public MyClass(bool condition) // 替换为你的实际判断逻辑
    {
        if(condition)
        {
            myD = StClass.myD1;
        }
        else
        {
            myD = StClass.myD2;
        }
    }
}

方案2:无法修改原有D1/D2定义时的适配写法

如果你没有权限修改StClass中已有的D1、D2委托定义,不需要自定义新的委托类型,直接用lambda表达式包装一层调用即可,编译器会自动完成适配,性能开销几乎可以忽略:

public class MyClass
{
    public Action<string> myD { get; set; }
   
    public MyClass(bool condition)
    {
        if(condition)
        {
            myD = s => StClass.myD1?.Invoke(s);
        }
        else
        {
            myD = s => StClass.myD2?.Invoke(s);
        }
    }
}

注意:如果你需要运行时读取StClass中myD1/myD2的最新赋值,上述写法可以直接满足;如果你需要固定构造时刻的委托引用,可先将静态委托赋值给本地变量再传入lambda。

方案3:必须保留MyClass内自定义D委托的实现

如果你因为业务要求必须保留MyClass中定义的D委托类型,赋值逻辑和方案2一致,直接通过lambda构造D类型的实例即可:

public class MyClass
{
    public delegate void D(string s);
    public D myD { get; set; }
   
    public MyClass(bool condition)
    {
        if(condition)
        {
            myD = s => StClass.myD1?.Invoke(s);
        }
        else
        {
            myD = s => StClass.myD2?.Invoke(s);
        }
    }
}

注意:不要尝试对不同类型的委托做强制类型转换,这类操作会在运行时抛出InvalidCastException;也不需要使用反射、Delegate.CreateDelegate这类重型方案实现适配,lambda包装是可读性、性能最优的实现方式。C# 对不同自定义委托做类型隔离是刻意的强类型设计,目的是避免委托被随意混用引发逻辑问题,不要用奇技淫巧绕开该机制。

内容的提问来源于stack exchange,提问作者IoTid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 12:57:14