该限制的真正原因是什么?这只是必须完成的工作吗?这在概念上很难吗?不可能吗?
当然,不能在字段中使用类型参数,因为它们总是可读写的。但这不可能是答案,不是吗?
提出这个问题的原因是我正在写一篇关于 C# 4 中的变体支持的文章,我觉得我应该解释一下为什么它仅限于委托(delegate)和接口(interface)。只是为了倒置举证责任。
更新: Eric 问了一个例子。
这个怎么样(还不知道这是否有意义:-))
public class Lookup<out T> where T : Animal {
public T Find(string name) {
Animal a = _cache.FindAnimalByName(name);
return a as T;
}
}
var findReptiles = new Lookup<Reptile>();
Lookup<Animal> findAnimals = findReptiles;
在一个类中拥有它的原因可能是在类本身中保存的缓存。请不要给不同类型的宠物取相同的名字!
顺便说一句,这让我想到了 optional type parameters in C# 5.0 :-)
更新 2: 我并不是说 CLR 和 C# 应该允许这样做。只是想了解是什么导致了它没有。
最佳答案
首先,正如 Tomas 所说,CLR 不支持它。
其次,这将如何运作?假设你有
class C<out T>
{ ... how are you planning on using T in here? ... }
T只能用在输出位置。正如您所注意到的,该类不能有任何 T 类型的字段,因为该字段可以写入。该类不能有任何采用 T 的方法,因为这些方法在逻辑上是写入的。假设您拥有此功能 - 您将如何利用它?
如果我们可以使具有类型 T 的只读字段合法,那么这对于不可变类将很有用;这样我们就可以大大减少它被不正确写入的可能性。但是很难想出其他允许以类型安全方式进行变化的场景。
如果你有这样的场景,我很乐意看到它。这将有助于有一天在 CLR 中实现这一点。
更新:见
Why isn't there generic variance for classes in C# 4.0?
有关此问题的更多信息。
关于c# - 为什么 C# (4.0) 不允许通用类类型中的协变和逆变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2541467/