c# 泛型 "in" 关键字
c# Generics "in" keyword
我最近被分配到现有应用程序的一些维护工作。我遇到了以下代码:
public interface IEntityService<T, in TKey>
{
T GetEntityById(TKey id);
IEnumerable<T> GetAll();
void Update(T entity);
void Delete(TKey key);
}
我不确定 in
关键字对第二个通用参数 TKey
的作用。
我看到了以下 MSDN 文章,它(应该)向我完美地解释了它:
in (Generic Modifier) (C# Reference)
然而,我并不真正理解它。内容如下:
For generic type parameters, the in keyword specifies that the type
parameter is contravariant. You can use the in keyword in generic
interfaces and delegates.
Contravariance enables you to use a less
derived type than that specified by the generic parameter. This allows
for implicit conversion of classes that implement variant interfaces
and implicit conversion of delegate types. Covariance and
contravariance in generic type parameters are supported for reference
types, but they are not supported for value types.
A type can be
declared contravariant in a generic interface or delegate if it is
used only as a type of method arguments and not used as a method
return type. Ref and out parameters cannot be variant.
An interface
that has a contravariant type parameter allows its methods to accept
arguments of less derived types than those specified by the interface
type parameter. For example, because in .NET Framework 4, in the
IComparer interface, type T is contravariant, you can assign an
object of the IComparer(Of Person) type to an object of the
IComparer(Of Employee) type without using any special conversion
methods if Employee inherits Person.
A contravariant delegate can be
assigned another delegate of the same type, but with a less derived
generic type parameter.
我想这是有道理的,但特别是引用
Contravariance enables you to use a less derived type than that
specified by the generic parameter.
它对 int
有什么用?有什么 "less derived type" 我会通过吗?
我注意到 int 的唯一引用是在你问题的最后一行。您确定 IEntityService<>
只能与 int
键一起使用吗?大概是为Compound Key(多列组成的主键)
而建
现在,例如在 NHibernate 中,对于复合键,您使用整个 class 来表示它们,因此您可以使用 table MyTable
a
class MyTableKey
{
public int Code;
public int SubCode;
}
如果你有一个辅助 table MuSubtable
连接到那个 table 你可以
class MySubtableKey : MyTableKey
{
public int SubSubCode;
}
其中 MySubtable
是一个 table,它的主键是 MyTable
(Code
+ SubCode
) 的完整主键加上另一个字段(SubSubCode
).
假设您有两个不同的实体,一个具有数据类型为 "integer" 的主键列,另一个使用 "string" 类型。
那么您可以将 IEntityService 用作:
public class PersonService : IEntityService<Person, int>
{
int _id;
...
}
public class LogService : IEntityService<Log, string>
{
string _id;
...
}
我最近被分配到现有应用程序的一些维护工作。我遇到了以下代码:
public interface IEntityService<T, in TKey>
{
T GetEntityById(TKey id);
IEnumerable<T> GetAll();
void Update(T entity);
void Delete(TKey key);
}
我不确定 in
关键字对第二个通用参数 TKey
的作用。
我看到了以下 MSDN 文章,它(应该)向我完美地解释了它:
in (Generic Modifier) (C# Reference)
然而,我并不真正理解它。内容如下:
For generic type parameters, the in keyword specifies that the type parameter is contravariant. You can use the in keyword in generic interfaces and delegates.
Contravariance enables you to use a less derived type than that specified by the generic parameter. This allows for implicit conversion of classes that implement variant interfaces and implicit conversion of delegate types. Covariance and contravariance in generic type parameters are supported for reference types, but they are not supported for value types.
A type can be declared contravariant in a generic interface or delegate if it is used only as a type of method arguments and not used as a method return type. Ref and out parameters cannot be variant.
An interface that has a contravariant type parameter allows its methods to accept arguments of less derived types than those specified by the interface type parameter. For example, because in .NET Framework 4, in the IComparer interface, type T is contravariant, you can assign an object of the IComparer(Of Person) type to an object of the IComparer(Of Employee) type without using any special conversion methods if Employee inherits Person.
A contravariant delegate can be assigned another delegate of the same type, but with a less derived generic type parameter.
我想这是有道理的,但特别是引用
Contravariance enables you to use a less derived type than that specified by the generic parameter.
它对 int
有什么用?有什么 "less derived type" 我会通过吗?
我注意到 int 的唯一引用是在你问题的最后一行。您确定 IEntityService<>
只能与 int
键一起使用吗?大概是为Compound Key(多列组成的主键)
现在,例如在 NHibernate 中,对于复合键,您使用整个 class 来表示它们,因此您可以使用 table MyTable
a
class MyTableKey
{
public int Code;
public int SubCode;
}
如果你有一个辅助 table MuSubtable
连接到那个 table 你可以
class MySubtableKey : MyTableKey
{
public int SubSubCode;
}
其中 MySubtable
是一个 table,它的主键是 MyTable
(Code
+ SubCode
) 的完整主键加上另一个字段(SubSubCode
).
假设您有两个不同的实体,一个具有数据类型为 "integer" 的主键列,另一个使用 "string" 类型。
那么您可以将 IEntityService 用作:
public class PersonService : IEntityService<Person, int>
{
int _id;
...
}
public class LogService : IEntityService<Log, string>
{
string _id;
...
}