c# - C# 数组的协变和逆变

标签 c# .net oop covariance contravariance

<分区>

在阅读 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)。替代方案是在执行时允许它,此时 strings[0] 将是对非字符串对象的引用,这显然是不好的.

另请参阅最近的博客文章:

关于c# - C# 数组的协变和逆变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17619139/

相关文章:

c# - 在 Linux 中运行从 .Net Framework 编译的 .exe 的方法

.net - 使用 gcServer ="true"为 .NET 设置垃圾收集器的经验

c# - WPF:DataGrid 上的水平滚动查看器在重新实例化绑定(bind)的 ObservableCollection 时捕捉到右侧

c# - 检索 x :Name or x:Key from Brush

c# - 来自对象的 MEF 元数据字典

java - 扩展时方法返回值发生变化

oop - 确定构造函数、初始化和重置方法的任务的最佳实践是什么

c# - 从 C++ 到 C# .Net Compact Framework 的结构转换问题

.net - 在.NET中获取Windows XP颜色

java - "code against"或 "resolve against"是什么意思?