C# c“仿制药”;在;关键词

C# c“仿制药”;在;关键词,c#,generics,contravariance,C#,Generics,Contravariance,我最近被分配到一个现有应用程序的一些维护工作。我遇到了以下代码: public interface IEntityService<T, in TKey> { T GetEntityById(TKey id); IEnumerable<T> GetAll(); void Update(T entity); void Delete(TKey key); } 公共接口IEntityService { T GetEntit

我最近被分配到一个现有应用程序的一些维护工作。我遇到了以下代码:

public interface IEntityService<T, in TKey>
{
    T GetEntityById(TKey id);    
    IEnumerable<T> GetAll();    
    void Update(T entity);    
    void Delete(TKey key);
}
公共接口IEntityService
{
T GetEntityById(TKey id);
IEnumerable GetAll();
无效更新(T实体);
作废删除(TKey);
}
我不确定关键字中的
对第二个泛型参数
TKey
有什么作用

我看到了下面的MSDN文章,这篇文章(应该)对我做了完美的解释:

然而,我并不真正理解它。它是这样说的:

对于泛型类型参数,in关键字指定 参数是逆变的。您可以在generic中使用in关键字 接口和委托

相反,您可以使用较少的 派生类型不是泛型参数指定的类型。这允许 用于实现变量接口的类的隐式转换 和委托类型的隐式转换。协方差和 支持引用泛型类型参数中的逆变 类型,但值类型不支持它们

类型可以是 在泛型接口或委托中声明的逆变(如果是 仅用作方法参数的类型,不用作方法 返回类型。Ref和out参数不能是变量

接口 具有逆变类型参数的允许其方法接受 派生类型少于接口指定类型的参数 类型参数。例如,因为在.NETFramework4中 IComparer接口,类型T是逆变的,您可以指定 I比较者(Person)类型的对象与 i比较者(雇员)类型,不使用任何特殊转换 方法,如果员工继承了Person

可以使用逆变委托 分配了另一个相同类型的委托,但派生的 泛型类型参数

我认为这是有道理的,但特别是引用

相反使您可以使用比该派生类型更少的派生类型 由泛型参数指定


它对
int
有什么用处?是否有任何“派生较少的类型”我会传入

我注意到int的唯一引用是在你问题的最后一行。您确定
IEntityService
仅与
int
键一起使用吗?它可能是为(由多列组成的主键)而构建的

现在,以NHibernate为例,对于复合键,您使用一个完整的类来表示它们,因此您可以使用for a table
MyTable
a

class MyTableKey 
{ 
    public int Code;
    public int SubCode;
}
如果有一个辅助表
MuSubtable
连接到该表,则可以

class MySubtableKey : MyTableKey 
{
    public int SubSubCode; 
}

其中,
MySubtable
是一个表,其主键为
MyTable
code
+
SubCode
)的完整主键以及另一个字段(
subsubsubcode
)。

假设您有两个不同的实体,一个实体的主键列的数据类型为“integer”,另一个使用的是“string”类型

然后您可以将IEntityService用作:

public class PersonService : IEntityService<Person, int>
{
   int _id;
   ...
}

public class LogService : IEntityService<Log, string>
{
   string _id;        
   ...
}
公共类PersonService:IEntityService
{
内部id;
...
}
公共类日志服务:IEntityService
{
字符串_id;
...
}

read
int
是一种值类型,如您所述,引用类型支持泛型类型参数中的协方差和逆变,但值类型不支持协方差和逆变。谢谢。所以答案是它什么也不做,可能不应该在那里,对吗?虽然它确实教会了我变化和不变性!所以这不是坏事;-)@bgs264我注意到,
int
的唯一参考是在你问题的最后一行。您确定
IEntityService
仅与
int
键一起使用吗?可能它是为(由多列组成的主键)构建的是的,你说得对。这就是为什么它是这样的原因。谢谢,@xanatos。如果你想把它写进一个答案,我会接受的。干杯