如何使这个泛型接口更类型化?
本文关键字:类型化 泛型接口 何使这 | 更新日期: 2023-09-27 18:01:51
考虑一个使用角色对象的类,维护一个集合来这样做。对于是否可以添加给定的角色,以及如果可以添加角色应该执行的操作,可能存在限制。
下面的IRoleSpecication旨在将add决策和操作的责任与维护集合的类分开,因此我有工作代码(即有用的),看起来像下面的代码示例。
但是我想做irolspecification。预插入处理程序使用泛型类型(TRole)而不是它当前使用的对象。我尝试为TRole添加一个参数,但我现有的代码希望它保持协变,而该方法需要它是不变的。
我该怎么做呢?
欢呼,
Berryl
public interface IRoleSpecification<in T>
{
bool CanAddRoleFor(T instance);
/// <summary>
/// Called when the newRole is about to be added to instance's collection of roles.
/// </summary>
/// <param name="instance">The instance.</param>
/// <param name="newRole">The new role.</param>
void OnPreInsert(T instance, object newRole);
...
}
public interface IEmployeeRoleSpecification<out TRole> : IRoleSpecification<EmployeeEx> where TRole : EmployeeRole
{
bool IsJobRole { get; set; }
}
public abstract class EmployeeRoleSpecification<TRole> : ValueObject, IEmployeeRoleSpecification<TRole>
where TRole : EmployeeRole
{
public virtual bool CanAddRoleFor(EmployeeEx employee) { return false; }
public virtual void OnPreInsert(EmployeeEx instance, object newRole) {
// jobRole helps enforce role constraints
// employee may have only one job role for 'job' role specs
if (IsJobRole) {
instance.JobRole = (TRole) newRole;
}
}
....
}
<标题> 更多代码public class EmployeeRole : EmployeeEx
{
private static readonly ISet<IEmployeeRoleSpecification<EmployeeRole>> _creationSpecs;
static EmployeeRole() {
_creationSpecs = new HashSet<IEmployeeRoleSpecification<EmployeeRole>>
{
new SalesmanRoleSpecification(),
new EngineerRoleSpecification(),
new ManagerRoleSpecification(),
};
}
}
public class SalesmanRoleSpecification : EmployeeRoleSpecification<Salesman>
{
public override bool CanAddRoleFor(EmployeeEx employee) { return _checkCanAddJobRole(employee); }
public SalesmanRoleSpecification() { IsJobRole = true; }
}
标题>
是否存在不能声明IEmployeeRoleSpecification为逆变的原因?
给定你发布的代码,这将编译:
public interface IEmployeeRoleSpecification<in TRole> : IRoleSpecification<EmployeeEx, EmployeeRole> where TRole : EmployeeRole
{
bool IsJobRole { get; set; }
}
public abstract class EmployeeRoleSpecification<TRole> : IEmployeeRoleSpecification<TRole>
where TRole : EmployeeRole
{
public virtual bool CanAddRoleFor(EmployeeEx employee) { return false; }
public virtual void OnPreInsert(EmployeeEx instance, EmployeeRole newRole) {
// jobRole helps enforce role constraints
// employee may have only one job role for 'job' role specs
if (IsJobRole) {
instance.JobRole = newRole;
}
}
public bool IsJobRole { get;set; }
}
public class EmployeeEx
{
public EmployeeRole JobRole { get;set;}
}
public class EmployeeRole { }
您可能无法做到这一点的原因是,如果IEmployeeRoleSpecification包含一个成员(您在这里省略了),则会暴露TRole (out
-going) -因为这时接口是协变的。泛型形参不能同时为共变和逆变。