考虑以下情况:
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>
答案 0 :(得分:1)
在你的例子中:
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);
}
答案 1 :(得分:-1)
因为C#规范要求构造函数参数。关于这个问题的规范答案是Why can't the C# constructor infer type?
值得注意的是几件事:我们几乎在C#6中得到它。你可以使用一个简单地调用构造函数的静态方法来破解它。例如
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);
}
}
为方便起见,我将它放在同名的非泛型类型上。