21

这种限制的真正原因是什么?只是必须完成的工作吗?概念上很难吗?这是不可能的吗?

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

这个问题的原因是我正在写一篇关于 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# 应该允许这样做。只是试图了解导致它没有的原因。

4

3 回答 3

21

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

其次,这将如何运作?假设你有

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

T 只能用于输出位置。正如您所注意到的,该类不能有任何类型为 T 的字段,因为可以写入该字段。该类不能有任何采用 T 的方法,因为这些是逻辑写入的。假设你有这个特性——你将如何利用它?

如果我们可以使拥有 T 类型的只读字段合法,这对于不可变类将很有用;这样我们就大大减少了它被不正确写入的可能性。但是很难想出其他允许以类型安全方式进行变化的场景。

如果你有这样的场景,我很乐意看到它。这将有助于有一天在 CLR 中实现这一点。

更新:见

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

有关此问题的更多信息。

于 2010-03-29T21:53:54.100 回答
8

据我所知,CLR 不支持此功能,因此添加此功能也需要在 CLR 方面进行大量工作。我相信 CLR 在 4.0 版之前实际上支持接口和委托的协变和逆变,因此这是一个相对简单的实现扩展。

(不过,为课程支持此功能肯定会很有用!)

于 2010-03-29T21:45:38.340 回答
1

如果它们被允许,则可以定义有用的 100% 类型安全(无内部类型转换)类或结构,如果它们的构造函数接受一个或多个 T 或 T 供应商,则它们的类型 T 是协变的。如果它们的构造函数接受一个或多个 T 消费者,则可以定义有用的 100% 类型安全的类或结构,这些类或结构相对于 T 是逆变的。除了使用“新”而不是使用静态工厂方法(很可能来自名称与接口名称相似的类)之外,我不确定类比接口有多大优势,但我可以当然,请参阅具有不可变结构支持协方差的用例。

于 2011-08-24T18:05:25.240 回答