c# - 从通用父类返回 `this` 需要在子类中强制转换

标签 c# builder-pattern

我正在使用 builder pattern ,已将重复代码提取到“帮助程序”类中,但重复代码的一个方面我仍然不满意。

构建器模式允许像这样链接实现代码:

Car car = new CarBuilder().Wheels(4).Convertible().Build();

每个方法 CarBuilder , WheelsConvertible返回构建器类 ( return this ) 和 Build 的相同实例方法返回新实例化的 Car .

这是我对通用构建器类的尝试:

public class Builder<T> where T : class 
{
    private Func<T, T> func;

    protected void SetInstantiator(Func<T, T> f) => this.func = f;

    protected void Chain(Action<T> action)
    {
        this.ChainFunc(action);
    }

    private ChainFunc(Action<T> action)
    {
        // SNIPPED
    }

    protected T Instantiate() => this.func(null);
}

这是我的通用构建器的实现:

public class CarBuilder : Builder<Car>
{
    public CarBuilder()
    {
        this.SetInstantiator(c => new Car());
        return this;
    }

    public CarBuilder Wheels(int wheels)
    {
        this.Chain(c => c.SetWheelCount(wheels));
        return this;
    }

    public CarBuilder Convertible()
    {
        this.Chain(c => c.RetractableRoof = true);
        return this;
    }

    public Car Build() => this.Instantiate();
}

困扰我的是重复的return this每次调用 Chain 后方法并认为我可以将其插入 Chain方法本身,即我想编写这样的代码:

    public CarBuilder Wheels(int wheels) =>
        this.Chain(c => c.SetWheelCount(wheels));

在生成器类中,我尝试将返回类型从 void 更改为至 Builder :

protected Builder Chain(Action<T> action)
{
    this.ChainFunc(action);
    return this;
}

... 但是编译器说返回类型必须是 Builder<T>

protected Builder<T> Chain(Action<T> action)
{
    this.ChainFunc(action);
    return this;
}

好吧,很公平,但在我的实现类中,我现在必须进行转换:

    public CarBuilder Wheels(int wheels) =>
        (CarBuilder)this.Chain(c => c.SetWheelCount(wheels));

所以我再次重复代码,所有方法现在都必须包含强制转换。将类类型从子类型传递到父类(super class)型感觉不对。

我想我可能在这里遗漏了一些基本的东西。我能否避免重复转换和必须从每个构建器实现方法中“返回这个”?

最佳答案

将逻辑保留在 protected 范围内的一种方法是添加一个被调用的静态方法而不是实例方法。静态方法可以使用隐式转换来返回调用者的类型

内部Builder<T>

protected void Chain(Action<T> action)
{
    //local chain logic
}

protected static BT Chain<BT>(BT builder, Action<T> action)
    where BT:Builder<T>
{
    builder.Chain(action);
    return builder;
}

内部调用 CarBuilder :

public CarBuilder Wheels(int wheels) => Chain(this , c => c.SetWheelCount(wheels));

public CarBuilder Convertible() => Chain(this, c => c.RetractableRoof = true);

关于c# - 从通用父类返回 `this` 需要在子类中强制转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43932828/

相关文章:

c# - Azure资源管理器-获取资源组的所有资源

c# - ASP.Net - 第二次回发后按钮上的 Bootstrap-Badge 丢失

c# - NumericUpDown UpdateEditText 在输入值时导致问题

design-patterns - 测试数据生成器是否应该为其非基元构造默认值?

java - 我应该如何将 Composite 模式包装到 Builder 模式中?

java - 使用反射的通用构建器模式类

oop - 铁路票价计算可以使用哪种设计模式?

c# - 使用 ExecuteNonQuery 时丢失\

c# - C# 相同项目中的命名空间

design-patterns - builder 模式和享元模式有什么区别?