与C#数组的协方差和逆差

参见英文答案 > Covariance and contravariance real world example                                    9个
在阅读维基百科关于协方差和逆变的文章的 section时,我遇到了以下粗体句:

First consider the array type constructor: from the type Animal we can make the type Animal[] (“array of animals”). Should we treat this as

  • Covariant: a Cat[] is a Animal[]
  • Contravariant: a Animal[] is a Cat[]
  • or neither (invariant)?

If we wish to avoid type errors, and the array supports both reading and writing elements, then only the third choice is safe. Clearly, not every Animal[] can be treated as if it were a Cat[], since a client reading from the array will expect a Cat, but an Animal[] may contain e.g. a Dog. So the contravariant rule is not safe.

Conversely, a Cat[] can not be treated as a Animal[]. It should always be possible to put a Dog into a Animal[]. With covariant arrays this can not be guaranteed to be safe, since the backing store might actually be an array of cats. So the covariant rule is also not safe—the array constructor should be invariant. Note that this is only a issue for mutable arrays; the covariant rule is safe for immutable (read-only) arrays.

我理解这个概念;我只是想要一个如何在C#中“无法保证安全”的例子.

它在编译时不安全.换句话说,这些代码在语言规则中是合法的,但在执行时失败,没有任何明确的强制转换来给出“这可能会失败”的大警告信号. CLR确保在执行时只有有效写入成功.例如:

string[] strings = new string[1];
object[] objects = strings;
objects[0] = new object();

这将在执行时抛出异常(ArrayTypeMismatchException).替代方案是在执行时允许它,此时字符串[0]将是对非字符串对象的引用,这显然是坏的.

另见最近的博客文章:

> One by me关于使用通用包装的性能和安全性
> One on immutable arrays来自BCL团队
> Part 2 of Eric Lippert’s blog series on variance in general(该系列主要针对仿制药,但这部分是针对阵列的)

相关文章
相关标签/搜索