C#泛型“在”关键字

bgs*_*264 5 c# generics contravariance

最近,我被分配去对现有应用程序进行一些维护工作。我遇到了以下代码:

public interface IEntityService<T, in TKey>
{
    T GetEntityById(TKey id);    
    IEnumerable<T> GetAll();    
    void Update(T entity);    
    void Delete(TKey key);
}
Run Code Online (Sandbox Code Playgroud)

我不确定in关键字对第二个通用参数的作用TKey

我碰到了以下MSDN文章,(应该)向我完美地解释了它:
在(通用修饰符)(C#参考)中

但是,我并没有真正理解它。它说的是:

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

借助Contravariance,您可以使用比通用参数指定的类型更少的派生类型。这允许实现变体接口的类的隐式转换和委托类型的隐式转换。引用类型支持泛型类型参数中的协方差和反方差,而值类型不支持它们的协方差和反方差。

如果类型仅用作方法参数的类型而不用作方法返回类型,则可以在通用接口或委托中将其声明为反变量。引用和输出参数不能为变量。

具有相反类型参数的接口允许其方法接受比接口类型参数指定的派生类型更少的参数。例如,因为在.NET Framework 4中,在IComparer接口中类型T是互变的,因此您可以将IComparer(Of Person)类型的对象分配给IComparer(Of Employee)类型的对象,而无需使用任何特殊的转换方法如果Employee继承Person。

可以为反委托代理分配相同类型的另一个委托,但是派生类型参数较少。

我认为这很有意义,但特别是引用

借助Contravariance,您可以使用比通用参数指定的类型更少的派生类型。

这对它有什么用int?有没有我会传入的“较少派生类型”?

xan*_*tos 4

我注意到 int 的唯一参考是在你问题的最后一行。您确定只能与钥匙IEntityService<>一起使用吗?int可能它是为复合键而构建的(由多列组成的主键)构建的

现在,例如在 NHibernate 中,对于复合键,您可以使用整个类来表示它们,因此您可以为表提供MyTable一个

class MyTableKey 
{ 
    public int Code;
    public int SubCode;
}
Run Code Online (Sandbox Code Playgroud)

如果您有一个辅助表MuSubtable连接到该表,那么您可以

class MySubtableKey : MyTableKey 
{
    public int SubSubCode; 
}
Run Code Online (Sandbox Code Playgroud)

其中MySubtable是一个表,其主键为MyTable( Code+ SubCode) 的完整主键加上另一个字段 ( SubSubCode)。