C# 如何使这个通用接口更类型化?
考虑一个使用角色对象并维护集合的类。对于是否可以添加给定角色,以及如果可以添加该角色,应该执行的操作,可能存在一些限制 下面的iRoleSpecification旨在将add决策和操作的责任从维护集合的类中分离出来,因此我有了与下面的代码示例类似的工作代码(即有用代码) 但是我想让IRoleSpecification.PreInsert处理程序使用泛型类型(TRole)而不是它当前使用的对象。我尝试为TRole添加一个参数,但我现有的代码希望它保持协变,而该方法需要它保持不变 我该怎么做 干杯,C# 如何使这个通用接口更类型化?,c#,generics,C#,Generics,考虑一个使用角色对象并维护集合的类。对于是否可以添加给定角色,以及如果可以添加该角色,应该执行的操作,可能存在一些限制 下面的iRoleSpecification旨在将add决策和操作的责任从维护集合的类中分离出来,因此我有了与下面的代码示例类似的工作代码(即有用代码) 但是我想让IRoleSpecification.PreInsert处理程序使用泛型类型(TRole)而不是它当前使用的对象。我尝试为TRole添加一个参数,但我现有的代码希望它保持协变,而该方法需要它保持不变 我该怎么做 干杯,
贝里尔
公共接口规范
{
bool CanAddRoleFor(例如);
///
///当newRole即将添加到实例的角色集合时调用。
///
///实例。
///新角色。
void OnPreInsert(T实例,对象newRole);
...
}
公共接口IEEmployeeRoleSpecification:IRoleSpecification,其中TRole:EmployeeRole
{
bool IsJobRole{get;set;}
}
公共抽象类EmployeeRoleSpecification:ValueObject,IEEmployeeRoleSpecification
TRole在哪里:EmployeeRole
{
公共虚拟bool CanAddRoleFor(EmployeeEx员工){return false;}
公共虚拟void OnPreInsert(EmployeeEx实例,对象newRole){
//jobRole有助于强制执行角色约束
//对于“职务”角色规范,员工只能有一个职务角色
if(IsJobRole){
instance.JobRole=(TRole)newRole;
}
}
....
}
更多代码
公共类EmployeeRole:EmployeeEx
{
私有静态只读ISet_creationSpecs;
静态EmployeeRole(){
_creationSpecs=新哈希集
{
新的SalesmanRoleSpecification(),
新工程师规范(),
新的ManagerRoleSpecification(),
};
}
}
公共类SalesManRole规范:EmployeeRole规范
{
public override bool-CanAddRoleFor(EmployeeEx-employee){return\u 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 { }
公共接口IEEmployeeRoleSpecification:IRoleSpecification其中TRole:EmployeeRole
{
bool IsJobRole{get;set;}
}
公共抽象类EmployeeRoleSpecification:IEEmployeeRoleSpecification
TRole在哪里:EmployeeRole
{
公共虚拟bool CanAddRoleFor(EmployeeEx员工){return false;}
公共虚拟void OnPreInsert(EmployeeEx实例,EmployeeRole newRole){
//jobRole有助于强制执行角色约束
//对于“职务”角色规范,员工只能有一个职务角色
if(IsJobRole){
instance.JobRole=newRole;
}
}
公共bool IsJobRole{get;set;}
}
公共类雇员
{
公共EmployeeRole作业角色{get;set;}
}
公共类EmployeeRole{}
您可能无法执行此操作的原因是,如果IEmployeeRoleSpecification包含一个成员(您在这里省略了),该成员将公开TRole(
out
-go),因为这样接口是协变的。泛型参数不能同时是协变和逆变。如何声明EmployeeEx.JobRole
?我怀疑这就是根本问题所在。如果它比EmployeeRole更具体,则不能从泛型参数中分配它。@driis。不,它只是“EmployeeRole JobRole{get;set;}是的,实际上。我需要在添加到我的帖子中的EmployeeRole类代码上保留允许的规范配置。当我使TRole逆变时,我得到一个编译错误,即规范不再可分配给IEEmployeeRoleSpecification。
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; }
}
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 { }