【发布时间】:2016-09-26 04:04:52
【问题描述】:
考虑以下场景:
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>
【问题讨论】:
-
编译器遵循规范。该规范需要类型参数,并且可以说这样做是有充分理由的,因为它避免了歧义和额外/复杂的规则:考虑
IEnumerable和IEnumerable<T>,它们都是单独的类型。问题的结尾令人困惑,因为 TKey 是赋予类型域限制的名称,与“运行时”.. -
编译器能否推断它并不重要——它不能推断,仅此而已。这很烦人,是的,但事实就是这样。 CLR 规范要求定义每个泛型类型参数。 F# 的类型推断比 C# 好得多,而且它仍然必须这样做(主要区别在于,当您调用只采用
TEntity的方法时,它会推断出正确的类型 :)。