通用抽象构建器属性需要强制转换

时间:2016-05-29 06:45:12

标签: c# generics builder creation-pattern

我构建了一个通用(抽象)构建器,它将提供基本的实现 对于将在测试期间使用的实体构建器。

这是实体基类

public abstract class Entity : IObjectState
{
    [NotMapped]
    public ObjectState ObjectState { get; set; }
}

这是 IKey接口

public interface IKey
{
    int Id { get; set; }
}

这是构建器类

public abstract class Builder<T> where T : Entity, IKey, new()
{
    protected int _id { get; set; }
    protected ObjectState _objectState { get; set; }

    public Builder()
    {
        _objectState = ObjectState.Added;
    }

    public virtual Builder<T> WithId(int id)
    {
        this._id = id;
        return this;
    }

    public virtual Builder<T> HavingObjectState(ObjectState objectState)
    {
        _objectState = objectState;
        return this;
    }

    public static implicit operator T(Builder<T> builder)
    {
        return new T
        {
            Id = builder._id,
            ObjectState = builder._objectState
        };
    }
}

这是一个示例 UnitBuilder 实现:

public class UnitBuilder : Builder<Unit>
{
    private string _shortDescription;
    private string _longDescription;

    public UnitBuilder WithShort(string shortDescription)
    {
        _shortDescription = shortDescription;
        return this;
    }

    public UnitBuilder WithLong(string longDescription)
    {
        _longDescription = longDescription;
        return this;
    }

    public static implicit operator Unit(UnitBuilder builder)
    {
        return new Unit
        {
            Id = builder._id,
            ObjectState = builder._objectState,
            Short = builder._shortDescription,
            Long = builder._longDescription
        };
    }
}

这就是我遇到的问题:

sample

错误:

  

错误CS1061'Builder'不包含的定义   'WithShort'并且没有扩展方法'WithShort'接受第一个   可以找到'Builder'类型的参数(你错过了吗?   使用指令或程序集引用?)



我理解发生了什么,但我想要一个比thirdUnit更好(更优雅)的解决方案。

更新:

根据建议,我将以下内容添加到UnitBuilder类:

public new UnitBuilder WithId(int id)
{
    return (UnitBuilder)base.WithId(id);
}

public new UnitBuilder WithObjectState(ObjectState objectState)
{
    return (UnitBuilder)base.WithObjectState(objectState);
}

但是现在我没有在基类中看到任何一点......这必须是一个 一般通用基类问题,其他人如何处理这个? 也许thirdUnit解决方案很优雅,但我对此感到困难? :)

2 个答案:

答案 0 :(得分:2)

答案很简单,您的基类构建器方法必须最后调用,并且不能与更具体的构建器类链接,因为它返回泛型。只需将代码更改为:

Unit secondUnit = new UnitBuilder()
    .WithShort("ShortDesc")
    .WithId(10);

就是这样!

答案 1 :(得分:0)

这是我最终的解决方案:

public abstract class Builder<TEntity, TBuilder>
        where TEntity : Entity, IKey, new()
        where TBuilder : Builder<TEntity, TBuilder>, new()
{
    protected int _id { get; set; }
    protected ObjectState _objectState { get; set; }

    public Builder()
    {
        _objectState = ObjectState.Added;
    }

    public virtual Builder<TEntity, TBuilder> WithId(int id)
    {
        this._id = id;
        return this;
    }

    public virtual Builder<TEntity, TBuilder> WithObjectState(ObjectState objectState)
    {
        this._objectState = objectState;
        return this;
    }

    public static implicit operator TEntity(Builder<TEntity, TBuilder> builder)
    {
        return new TEntity
        {
            Id = builder._id,
            ObjectState = builder._objectState
        };
    }
}