为什么我需要在泛型类上显式地定义泛型参数'
本文关键字:泛型 定义 参数 泛型类 为什么 | 更新日期: 2023-09-27 18:08:39
考虑以下场景:
public interface IEntity<TKey>
{
TKey { get; set; }
}
public interface IRepository<TEntity, TKey>
where TEntity : IEntity<TKey>
{
void Store(TEntity entity);
void Delete(TKey key);
}
为什么我需要显式地将TKey
作为通用参数添加到IRepository
?
编译器不能从TEntity
的类型推断或推断出来吗?
我想实现这样的事情:
public interface IRepository<TEntity>
where TEntity : IEntity<TKey>
{
void Store(TEntity entity);
void Delete(TKey key);
}
不像TKey
只在运行时被知道:
IRepository<User> userRepo = new ConcreteRepository<User>();
User
实现IEntity<string>
在您的示例中:
public interface IRepository<TEntity>
where TEntity : IEntity<TKey> {
void Store(TEntity entity);
void Delete(TKey key);
}
TKey
是未定义的类型参数。您可以说where TEntity : IEntity<string>
,因为string
是一个已定义的类型。但是,如果要使用类型参数,则需要首先定义它。
注意编译器不知道这里的TKey
是什么。是一种类型吗?它是泛型类型参数吗?
您可能能够做这样的事情,但它将不再是强类型的TEntity
。这可能是可接受的,也可能是不可接受的:
public interface IRepository<TKey> {
void Store(IEntity<TKey> entity);
void Delete(TKey key);
}
因为c#规范要求构造函数参数是这样的。关于这个问题的标准答案是:为什么c#构造函数不能推断类型?
值得注意的是:我们几乎在c# 6中实现了它。您可以通过使用Static方法来绕过它,该方法只需调用构造函数。例如
public class Entity<TKey>
{
public Entity(TKey k)
{
}
}
public static class Entity
{
public static Entity<MyKey> Create<MyKey>(MyKey mk)
{
return new Entity<MyKey>(mk);
}
}
为方便起见,我把它放在一个同名的非泛型类型上