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

C#子类重写方法时签名不匹配的正确解决方式

编译期保证类型安全的解决方案

核心思路是通过泛型约束在编译阶段绑定Action与对应的EventArgs类型,彻底避免运行时类型检查的不确定性。

方案一:泛型基类直接约束(适用于无需跨类型多态的场景)

重构基类为泛型类,指定EventArgs的类型约束,子类继承时明确具体的EventArgs类型:

public class ActionEventArgs : EventArgs
{
    public Creature actor;
}

public class LocationEventArgs : ActionEventArgs
{
    public Location loc;
}

// 泛型基类,约束TEventArgs必须继承自ActionEventArgs
public abstract class Action<TEventArgs> where TEventArgs : ActionEventArgs
{
    public abstract void Do(object sender, TEventArgs e);
}

// 子类直接绑定LocationEventArgs,重写方法签名完全匹配
public class LocationAction : Action<LocationEventArgs>
{
    public override void Do(object sender, LocationEventArgs e)
    {
        // 直接使用e.loc,编译阶段已保证类型正确
        // ... 业务逻辑实现
    }
}

public class MainClass
{
    // 直接声明为具体的泛型类型,编译期约束类型匹配
    public Action<LocationEventArgs> a { get; protected set; }

    public void InitAction()
    {
        a = new LocationAction();
    }

    public void DoAction(Creature actor, Location location)
    {
        a.Do(this, new LocationEventArgs() { actor = actor, loc = location });
    }
}

方案二:泛型+非泛型接口(支持多态场景)

如果需要在MainClass中兼容多种Action类型(多态),可以先定义非泛型接口,再让泛型基类实现该接口,通过显式接口实现完成类型转换(泛型约束保证转换安全):

public class ActionEventArgs : EventArgs
{
    public Creature actor;
}

public class LocationEventArgs : ActionEventArgs
{
    public Location loc;
}

// 非泛型接口,用于多态场景
public interface IAction
{
    void Do(object sender, ActionEventArgs e);
}

// 泛型基类,实现IAction并约束EventArgs类型
public abstract class Action<TEventArgs> : IAction where TEventArgs : ActionEventArgs
{
    // 子类重写此方法,直接使用具体的TEventArgs类型
    public abstract void Do(object sender, TEventArgs e);

    // 显式实现接口,完成类型转换(泛型约束保证转换安全)
    void IAction.Do(object sender, ActionEventArgs e)
    {
        Do(sender, (TEventArgs)e);
    }
}

public class LocationAction : Action<LocationEventArgs>
{
    public override void Do(object sender, LocationEventArgs e)
    {
        // 编译期确保e是LocationEventArgs,可直接访问loc属性
        // ... 业务逻辑实现
    }
}

public class MainClass
{
    // 使用非泛型接口实现多态
    public IAction a { get; protected set; }

    public void InitAction()
    {
        a = new LocationAction();
    }

    public void DoAction(Creature actor, Location location)
    {
        // 此处传入明确的LocationEventArgs,与Action类型匹配
        a.Do(this, new LocationEventArgs() { actor = actor, loc = location });
    }
}

方案说明

  • 泛型约束确保了Action子类只能绑定指定的EventArgs类型,编译阶段就能检测到类型不匹配的错误,无需依赖运行时检查。
  • 方案二通过非泛型接口保留了多态能力,同时利用泛型约束保证了类型转换的安全性,避免了无效转换的风险。

内容的提问来源于stack exchange,提问作者Илья Кротов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:30:57