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

重载已重写方法:能否在派生类实现多重载方法以重写方式调用?

问题

能否在派生类中实现多个重载方法,使其可以像重写方法一样被调用?我未找到相关资料。

示例代码如下:

class BaseClass
{
    public virtual void Do(object o)
    {
        DoNothing();
    }
}

class ChildClass : BaseClass
{
    public override void Do(object o)
    {
        Write("Something");
    }
    
    public void Do(string s) //override?, new?
    {
        Write(s);
    }
}

我知道通过派生类对象可以调用Do(string s):

ChildClass c = new ChildClass();
c.Do("text");

执行结果:"text"

但通过基类引用指向派生类对象时,会调用Do(object o):

BaseClass c = new ChildClass();
c.Do("text");

执行结果:"Something"

我希望能避免以下写法:

public override void Do(object o)
{
    if (o is string)
        Write(s);
    else
        Write("Something");
}
解决方案

你想要的「通过基类引用自动匹配派生类重载方法」的行为,在C#静态绑定规则下无法直接实现——因为方法重载的匹配是编译时完成的,基类仅定义了Do(object)方法,编译器会直接把c.Do("text")绑定到基类的Do(object),运行时虽会执行派生类的重写版本,但不会再去匹配派生类新增的重载。

以下是几种更优雅的替代方案:

1. 在基类中定义所有需要的重载(标记为virtual)

若可以修改基类,直接把需要的重载都定义为虚方法,派生类就能针对性重写:

class BaseClass
{
    public virtual void Do(object o)
    {
        DoNothing();
    }

    public virtual void Do(string s)
    {
        // 基类默认可转发给Do(object),也可单独实现逻辑
        Do(s as object);
    }
}

class ChildClass : BaseClass
{
    public override void Do(object o)
    {
        Write("Something");
    }
    
    public override void Do(string s)
    {
        Write(s);
    }
}

此时用基类引用调用Do("text"),编译时会匹配基类的Do(string)重载,运行时自动执行派生类的重写版本。

2. 使用访问者模式

如果你的类型体系相对固定,可通过访问者模式让不同类型参数触发对应逻辑:

// 定义访问者接口
public interface IDoVisitor
{
    void Visit(string s);
    void Visit(object o);
}

// 基类修改为接受访问者
class BaseClass
{
    public virtual void Accept(IDoVisitor visitor, object o)
    {
        visitor.Visit(o);
    }
}

class ChildClass : BaseClass
{
    public override void Accept(IDoVisitor visitor, object o)
    {
        // 优先匹配具体类型
        if (o is string s)
            visitor.Visit(s);
        else
            visitor.Visit(o);
    }
}

// 实现具体处理逻辑
public class DoVisitor : IDoVisitor
{
    public void Visit(string s)
    {
        Write(s);
    }

    public void Visit(object o)
    {
        Write("Something");
    }
}

调用方式:

BaseClass c = new ChildClass();
c.Accept(new DoVisitor(), "text"); // 会触发Visit(string)逻辑

3. 使用动态绑定(谨慎使用)

若不想修改基类,可借助dynamic绕过编译时绑定检查,让运行时匹配最合适的重载:

BaseClass c = new ChildClass();
dynamic param = "text";
c.Do(param); // 运行时会匹配ChildClass的Do(string)

但这种方式会丢失编译时类型检查,容易引发运行时错误,仅适合类型明确的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:20:21