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

如何优化含公共成员的A、B类组合输入类C的属性同步实现?

如何优雅实现包含A、B组合的C类输入服务?

首先得明确咱们的核心需求:让C类能统一设置InputBase里的公共属性,自动同步到内部的A和B实例,同时能方便获取这些属性,还要解决C类是否该继承InputBase的疑问。

先分析现有问题

当前C类只是简单包裹A和B的实例,导致更新公共属性时要分别操作c.A.DateCreated和c.B.DateCreated,不仅繁琐还容易漏改。咱们要做的就是把公共属性的操作入口统一到C类上,内部自动同步。

方案一:让C继承InputBase(推荐,支持多态)

如果你的服务里有接收InputBase类型的方法,或者希望C能和A、B保持统一的基类接口,那让C继承InputBase是最优解。通过重写基类的公共属性,在Setter里同步A和B的对应值,Getter直接取其中一个实例的属性(因为同步后两者值一致)。

代码示例:

public abstract class InputBase 
{ 
    public bool Option1 { get; set; } 
    public decimal Rate { get; set; } 
    public DateTime DateCreated { get; set; } 
} 

public class A : InputBase { public decimal Fee { get; set; } } 
public class B : InputBase { public decimal Fee { get; set; } }

public class C : InputBase
{
    // 自动初始化A和B实例,避免用户手动创建
    public A A { get; set; } = new A();
    public B B { get; set; } = new B();

    // 重写基类公共属性,实现同步逻辑
    public override bool Option1
    {
        get => A.Option1;
        set
        {
            A.Option1 = value;
            B.Option1 = value;
        }
    }

    public override decimal Rate
    {
        get => A.Rate;
        set
        {
            A.Rate = value;
            B.Rate = value;
        }
    }

    public override DateTime DateCreated
    {
        get => A.DateCreated;
        set
        {
            A.DateCreated = value;
            B.DateCreated = value;
        }
    }
}

这样使用起来就完全符合你的期望:

var c = new C();
c.DateCreated = DateTime.Now; // 统一设置,自动同步到A和B
var createdDate = c.A.DateCreated; // 和c.DateCreated值一致

额外优化:防止外部修改A/B实例导致不一致

如果担心外部代码直接替换A或B的实例(比如c.A = new A();)导致属性不同步,可以把A和B的Setter设为私有,只保留Getter:

public A A { get; } = new A();
public B B { get; } = new B();

如果必须允许替换A/B实例,那在属性的Setter里补充同步逻辑:

private A _a = new A();
public A A
{
    get => _a;
    set
    {
        _a = value;
        // 把当前C的公共属性同步到新的A实例
        _a.Option1 = base.Option1;
        _a.Rate = base.Rate;
        _a.DateCreated = base.DateCreated;
    }
}

// B的Setter同理处理

方案二:C不继承InputBase(适合无需多态场景)

如果你的服务不需要C作为InputBase的子类,也可以在C类中直接定义和InputBase完全一致的公共属性,实现同样的同步逻辑:

public class C
{
    public A A { get; set; } = new A();
    public B B { get; set; } = new B();

    public bool Option1
    {
        get => A.Option1;
        set
        {
            A.Option1 = value;
            B.Option1 = value;
        }
    }

    public decimal Rate
    {
        get => A.Rate;
        set
        {
            A.Rate = value;
            B.Rate = value;
        }
    }

    public DateTime DateCreated
    {
        get => A.DateCreated;
        set
        {
            A.DateCreated = value;
            B.DateCreated = value;
        }
    }
}

这个方案的用法和方案一完全一样,只是C不能当作InputBase来使用。

关于Getter的处理逻辑

因为我们在Setter里已经确保了A和B的公共属性值完全一致,所以Getter只需要取其中一个实例的属性即可(比如示例中的A)。如果要更严谨,可以在Getter里加个校验,确保A和B的属性值一致,避免外部直接修改A/B的属性导致不一致:

public override DateTime DateCreated
{
    get
    {
        if (A.DateCreated != B.DateCreated)
        {
            // 可以抛出异常,或者统一取A的值,根据业务需求处理
            throw new InvalidOperationException("A和B的DateCreated属性不一致");
        }
        return A.DateCreated;
    }
    // Setter逻辑不变
}

总结最优实现方式

  1. 优先选择方案一:让C继承InputBase,这样既能统一操作公共属性,又能支持多态,符合面向对象的设计原则。
  2. 自动初始化A/B实例:在C的属性初始化或构造函数中创建A和B的实例,避免用户手动编写繁琐的初始化代码。
  3. 控制A/B的修改权限:根据业务需求,决定是否允许外部替换A/B实例,若允许则补充同步逻辑,防止属性不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:34:00