C# 如何使这个通用接口更类型化?

C# 如何使这个通用接口更类型化?,c#,generics,C#,Generics,考虑一个使用角色对象并维护集合的类。对于是否可以添加给定角色,以及如果可以添加该角色,应该执行的操作,可能存在一些限制 下面的iRoleSpecification旨在将add决策和操作的责任从维护集合的类中分离出来,因此我有了与下面的代码示例类似的工作代码(即有用代码) 但是我想让IRoleSpecification.PreInsert处理程序使用泛型类型(TRole)而不是它当前使用的对象。我尝试为TRole添加一个参数,但我现有的代码希望它保持协变,而该方法需要它保持不变 我该怎么做 干杯,

考虑一个使用角色对象并维护集合的类。对于是否可以添加给定角色,以及如果可以添加该角色,应该执行的操作,可能存在一些限制

下面的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 { }