一尘不染

为什么C#(4.0)在通用类类型中不允许协变和矛盾?

c#

该限制的 真正 原因是什么?只是必须要做的工作吗?在概念上难吗?不可能吗

当然,不能在字段中使用类型参数,因为它们始终是可读写的。但这不是答案,是吗?

出现此问题的原因是,我正在用C#4写一篇有关差异支持的文章,我觉得我应该解释为什么它仅限于委托和接口。只是为了推翻举证责任。

更新: 埃里克问一个例子。

怎么办呢(不知道那是否有意义:-))

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;

在一个类中拥有该缓存的原因可能是该类本身中保留的缓存。而且,请不要给不同类型的宠物起同样的名字!

顺便说一句,这使我进入C#5.0中的可选类型参数 :-)

更新2: 我并不是说CLR和C#应该允许这样做。只是想了解导致它失败的原因。


阅读 421

收藏
2020-05-19

共1个答案

一尘不染

首先,正如Tomas所说,CLR不支持它。

第二,那将如何工作?假设你有

class C<out T>
{ ... how are you planning on using T in here? ... }

T仅可用于输出位置。如您所述,该类不能有任何类型为T的字段,因为该字段可以写入。该类不能有任何采用T的方法,因为这些方法在逻辑上是可写的。假设您具有此功能-
您将如何利用它?

如果我们可以说拥有一个类型T的只读字段,这对于不可变的类将很有用。这样,我们将大大减少不正确写入的可能性。但是很难提出其他允许以类型安全的方式进行变化的方案。

如果您有这种情况,我很乐意看到。这将指向有一天在CLR中实现这一点。

更新:请参阅

为什么C#4.0中的类没有通用差异?

有关此问题的更多信息。

2020-05-19