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

如何避免C#不同类中重复定义相同属性?多继承场景优化方案

问题与优化方案

问题背景

我需要一个同时包含VehicleConfig和ExtendedTransportConfig所有属性的类,但C#不支持多继承。目前我通过创建ExtendedVehicleConfig并重复定义VehicleConfig的所有属性来实现,让Car3Config继承它。但每次修改VehicleConfig的属性都要同步修改ExtendedVehicleConfig,维护成本很高。考虑过用接口,但需要改动现有类结构,且还是要重复定义属性,想找更优的解决方案。

当前代码结构

public class TransportConfig
{
   public int Prop1 { get; set; }
   ...
}

public class VehicleConfig : TransportConfig
{
   public int Prop2 { get; set; }
   ...
}

public class Car1Config : VehicleConfig 
{
   public int Prop3 { get; set; }
   ...
}


public class ExtendedTransportConfig : TransportConfig
{
   public int Prop4 { get; set; }
   ...
}

public class Car2Config : ExtendedTransportConfig  
{
   public int Prop5 { get; set; }
   ...
}

当前使用的(不理想的)解决方案

public class Car3Config : ExtendedVehicleConfig  
{
   public int Prop6 { get; set; }
   ...
}

public class ExtendedVehicleConfig : ExtendedTransportConfig
{
   public int Prop2 { get; set; }
   ...
}

更好的解决方案

方案1:组合优先(推荐,无需修改原有类)

利用组合而非继承的思路,直接在Car3Config中包含VehicleConfig和ExtendedTransportConfig的实例,彻底避免属性重复定义:

public class Car3Config
{
    // 直接持有两个配置类的实例
    public VehicleConfig VehicleSettings { get; set; } = new VehicleConfig();
    public ExtendedTransportConfig ExtendedTransportSettings { get; set; } = new ExtendedTransportConfig();

    // 可选:如果需要直接访问属性而非通过子实例,可添加包装属性
    public int Prop1 => ExtendedTransportSettings.Prop1;
    public int Prop2 => VehicleSettings.Prop2;
    public int Prop4 => ExtendedTransportSettings.Prop4;

    // 自身独有的属性
    public int Prop6 { get; set; }
    ...
}

这样修改VehicleConfig或ExtendedTransportConfig的属性时,Car3Config会自动同步,完全不需要手动维护重复代码。使用时可以直接通过子实例访问所有属性,或者通过包装属性简化调用。

方案2:接口提取+组合(面向接口设计)

如果希望遵循面向接口原则,可以先将各配置类的属性提取到接口中,再通过组合实现属性复用:

// 定义基础接口
public interface ITransportConfig
{
    int Prop1 { get; set; }
}

public interface IVehicleConfig : ITransportConfig
{
    int Prop2 { get; set; }
}

public interface IExtendedTransportConfig : ITransportConfig
{
    int Prop4 { get; set; }
}

// 原有类实现对应接口
public class TransportConfig : ITransportConfig
{
    public int Prop1 { get; set; }
    ...
}

public class VehicleConfig : TransportConfig, IVehicleConfig
{
    public int Prop2 { get; set; }
    ...
}

public class ExtendedTransportConfig : TransportConfig, IExtendedTransportConfig
{
    public int Prop4 { get; set; }
    ...
}

// Car3Config实现两个接口,通过组合实例委托属性
public class Car3Config : IVehicleConfig, IExtendedTransportConfig
{
    private readonly VehicleConfig _vehicleConfig = new VehicleConfig();
    private readonly ExtendedTransportConfig _extendedConfig = new ExtendedTransportConfig();

    // 实现接口属性,直接委托给组合的实例
    public int Prop1 
    { 
        get => _extendedConfig.Prop1; 
        set => _extendedConfig.Prop1 = value; 
    }

    public int Prop2 
    { 
        get => _vehicleConfig.Prop2; 
        set => _vehicleConfig.Prop2 = value; 
    }

    public int Prop4 
    { 
        get => _extendedConfig.Prop4; 
        set => _extendedConfig.Prop4 = value; 
    }

    public int Prop6 { get; set; }
    ...
}

这个方案的优势是定义清晰,符合SOLID原则,但需要对原有类做少量改动(实现接口),后续属性修改只需调整接口即可同步所有实现类。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:42:50