通用抽象构建器属性需要转换
Generic abstract builder properties needs casting
我构建了一个通用(抽象)构建器,它将提供基本实现
对于将在测试期间使用的实体构建器。
这是实体库class:
public abstract class Entity : IObjectState
{
[NotMapped]
public ObjectState ObjectState { get; set; }
}
这是IKey接口:
public interface IKey
{
int Id { get; set; }
}
这是 Builder class:
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
};
}
}
这就是我遇到的问题:
错误:
Error CS1061 'Builder' does not contain a definition for
'WithShort' and no extension method 'WithShort' accepting a first
argument of type 'Builder' could be found (are you missing a
using directive or an assembly reference?)
我明白发生了什么,但我想要一个比 thirdUnit
.
更好(更优雅)的解决方案
更新:
根据建议,我将以下内容添加到 UnitBuilder
class:
public new UnitBuilder WithId(int id)
{
return (UnitBuilder)base.WithId(id);
}
public new UnitBuilder WithObjectState(ObjectState objectState)
{
return (UnitBuilder)base.WithObjectState(objectState);
}
但现在我在基地中看不到任何一点 class...这必须是
general generic base class 问题,其他人是怎么处理的?
也许 thirdUnit
解决方案很优雅,但我只是很难理解它? :)
答案很简单,您的基础 class 构建器方法必须最后调用,并且不能与更具体的构建器 class 链接,因为它 returns 是通用的。所以只需将您的代码更改为:
Unit secondUnit = new UnitBuilder()
.WithShort("ShortDesc")
.WithId(10);
就是这样!
这是我的最终解决方案:
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
};
}
}
我构建了一个通用(抽象)构建器,它将提供基本实现 对于将在测试期间使用的实体构建器。
这是实体库class:
public abstract class Entity : IObjectState
{
[NotMapped]
public ObjectState ObjectState { get; set; }
}
这是IKey接口:
public interface IKey
{
int Id { get; set; }
}
这是 Builder class:
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
};
}
}
这就是我遇到的问题:
错误:
Error CS1061 'Builder' does not contain a definition for 'WithShort' and no extension method 'WithShort' accepting a first argument of type 'Builder' could be found (are you missing a using directive or an assembly reference?)
我明白发生了什么,但我想要一个比 thirdUnit
.
更新:
根据建议,我将以下内容添加到 UnitBuilder
class:
public new UnitBuilder WithId(int id)
{
return (UnitBuilder)base.WithId(id);
}
public new UnitBuilder WithObjectState(ObjectState objectState)
{
return (UnitBuilder)base.WithObjectState(objectState);
}
但现在我在基地中看不到任何一点 class...这必须是
general generic base class 问题,其他人是怎么处理的?
也许 thirdUnit
解决方案很优雅,但我只是很难理解它? :)
答案很简单,您的基础 class 构建器方法必须最后调用,并且不能与更具体的构建器 class 链接,因为它 returns 是通用的。所以只需将您的代码更改为:
Unit secondUnit = new UnitBuilder()
.WithShort("ShortDesc")
.WithId(10);
就是这样!
这是我的最终解决方案:
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
};
}
}