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

C#如何解决派生类仅可继承一个基类的单继承限制问题

C#单继承限制的优雅解决方案

核心思路说明

C#限制类仅能单继承是刻意设计,目的是规避多继承带来的菱形继承歧义等问题,并非短板。针对你的场景,采用组合优于继承的设计思路,即可同时满足DRY原则和整洁代码要求,也能解决接口无法定义字段的限制。


方案1:组合+接口暴露(兼容所有C#版本,最推荐)

实现步骤

  1. 定义颜色相关的公开接口,仅暴露需要的属性和方法
  2. 原有CColor类实现该接口,逻辑保持不变
  3. 彩色形状类继承对应形状基类,同时实现颜色接口,所有颜色相关逻辑直接委托给内部组合的CColor实例即可

代码实现

// 1. 定义颜色接口
public interface IColored
{
    int R { get; set; }
    int G { get; set; }
    int B { get; set; }
    void MixColorWith(int r, int g, int b);
}

// 2. 原有CColor实现接口,逻辑不变
public class CColor : IColored
{
    public int R { get; set; }
    public int G { get; set; }
    public int B { get; set; }
    public void MixColorWith(int r, int g, int b) 
    { 
        /*原有实现代码保持不变*/
    }
}

// 3. 彩色三角形实现
public class CColoredTriangle : CTriangle, IColored
{
    // 组合CColor实例,所有逻辑委托给它
    private readonly CColor _color = new CColor();
    
    protected CColoredTriangle(double x, double y) : base(x, y) { }

    // 直接转发属性和方法,无需重复实现逻辑
    public int R
    {
        get => _color.R;
        set => _color.R = value;
    }
    public int G
    {
        get => _color.G;
        set => _color.G = value;
    }
    public int B
    {
        get => _color.B;
        set => _color.B = value;
    }
    public void MixColorWith(int r, int g, int b) => _color.MixColorWith(r, g, b);
}

// 彩色矩形实现同理,核心逻辑仅在CColor中定义一次,不违反DRY原则
public class CColoredRectangle : CRectangle, IColored
{
    private readonly CColor _color = new CColor();
    
    protected CColoredRectangle(double x, double y) : base(x, y) { }

    public int R
    {
        get => _color.R;
        set => _color.R = value;
    }
    public int G
    {
        get => _color.G;
        set => _color.G = value;
    }
    public int B
    {
        get => _color.B;
        set => _color.B = value;
    }
    public void MixColorWith(int r, int g, int b) => _color.MixColorWith(r, g, b);
}

优势

  • 原有CRectangle、CTriangle类无需任何修改,不会引入不需要的颜色相关成员,符合整洁代码要求
  • 颜色逻辑仅在CColor中实现一次,完全符合DRY原则
  • 所有彩色形状都可以通过IColored接口统一处理,符合面向接口的设计规范

方案2:C# 8+ 精简实现(依赖高版本C#)

如果你的项目使用C# 8及以上版本,可以通过默认接口方法+共享存储进一步简化代码,无需手动编写转发逻辑:

public interface IColored
{
    // 全局存储所有IColored实例的颜色数据
    private static readonly ConditionalWeakTable<IColored, CColor> _colorStore = new();

    int R 
    { 
        get => GetOrCreateColor().R; 
        set => GetOrCreateColor().R = value; 
    }
    int G 
    { 
        get => GetOrCreateColor().G; 
        set => GetOrCreateColor().G = value; 
    }
    int B 
    { 
        get => GetOrCreateColor().B; 
        set => GetOrCreateColor().B = value; 
    }

    void MixColorWith(int r, int g, int b) => GetOrCreateColor().MixColorWith(r, g, b);

    private CColor GetOrCreateColor()
    {
        if (!_colorStore.TryGetValue(this, out var color))
        {
            color = new CColor();
            _colorStore.Add(this, color);
        }
        return color;
    }
}

// 彩色类实现不需要写任何额外代码
public class CColoredTriangle : CTriangle, IColored
{
    protected CColoredTriangle(double x, double y) : base(x, y) { }
}

public class CColoredRectangle : CRectangle, IColored
{
    protected CColoredRectangle(double x, double y) : base(x, y) { }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 21:54:03