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

C#函数继承与代码复用:消除Draw方法重复实现问题

解决方案

要消除代码重复同时保留多态调用能力,你可以通过抽象基类封装公共逻辑,利用GetType()自动获取实例的真实类型特性来实现需求,无需在子类中重复编写Draw方法。

重构后的代码示例

// 保留原接口(可选,若需要基于接口编程则保留)
public interface IShapes
{
    void Draw();
}

// 抽象基类封装公共Draw逻辑
public abstract class ShapeBase : IShapes
{
    public void Draw()
    {
        // GetType()会返回当前实例的真实子类类型
        var className = GetType().FullName?.Substring(GetType().FullName.IndexOf('.') + 1);
        Console.WriteLine($"{className} - Draw");
    }
}

// 子类仅需继承基类,无需重写Draw
public class Square : ShapeBase { }

public class Circle : ShapeBase { }

调用代码(与原需求一致)

var shapes = new List<IShapes>();
shapes.Add(new Circle());
shapes.Add(new Square());

shapes.ForEach(s => s.Draw());

执行后将输出:

Circle - Draw
Square - Draw

为什么你之前的尝试失败

你使用public new void Draw()的方式是隐藏基类方法,而非重写,这会破坏多态性:当通过基类/接口类型调用时,执行的是基类的方法而非子类的。而这里根本不需要子类重写Draw——基类中的GetType()会自动识别当前实例的真实子类类型,直接复用基类逻辑即可。

扩展场景:子类需要自定义Draw逻辑

如果后续子类需要添加专属逻辑,可以将基类的Draw定义为virtual,子类通过override扩展:

public abstract class ShapeBase : IShapes
{
    public virtual void Draw()
    {
        var className = GetType().FullName?.Substring(GetType().FullName.IndexOf('.') + 1);
        Console.WriteLine($"{className} - Draw");
    }
}

public class Square : ShapeBase
{
    public override void Draw()
    {
        // 先执行基类逻辑
        base.Draw();
        // 添加子类专属逻辑
        Console.WriteLine("Square has 4 sides");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 19:59:54