协变和逆变用C#数组 [英] Covariance and Contravariance with C# Arrays

查看:169
本文介绍了协变和逆变用C#数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读有关协变和逆变的一篇文章的部分维基百科,我跑进以下,加粗的句子:

While reading a section of an article about covariance and contravariance at Wikipedia, I ran into the following, bolded sentence:

首先考虑的数组类型的构造函数:从类型动物我们可以做的类型动物[] (阵列的动物)。我们应该把它当作

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#。

I understand the concept; I just want an example of how this "cannot be guaranteed to be safe" in C#.

推荐答案

这是不是安全的在编译的时候的。换句话说,有code这是合法的语言规则,但未能在执行时,没有任何明确的铸造给予这可能会失败的一大警讯。在CLR确保只有合法的写操作时的执行的时间成功。例如:

It's not safe at compile time. In other words, there's code which is legal by the language rules, but fails at execution time, without any explicit casting to give a big warning sign of "this might fail". The CLR makes sure that only valid writes succeed at execution time. For example:

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

这将抛出一个异常(<一href="http://msdn.microsoft.com/en-us/library/system.arraytypemismatchexception.aspx"><$c$c>ArrayTypeMismatchException)在执行时,另一个选择是到过的允许的它在执行时,此时字符串[0] 将是一个引用非字符串对象,这显然是不好的。

That will throw an exception (ArrayTypeMismatchException) at execution time. The alternative would have been to allow it at execution time, at which point strings[0] would have been a reference to a non-string object, which would clearly be bad.

另请参见近期博客文章:

See also recent blog posts:

  • <一个href="http://msmvps.com/blogs/jon_skeet/archive/2013/06/22/array-covariance-not-just-ugly-but-slow-too.aspx">One由我有关使用一个通用的包装性能和安全性
  • 从BCL一对永恒不变的阵列的团队
  • <一个href="http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx">Part 2埃里克利珀的博客系列方差一般(该系列产品主要针对仿制药,但是这部分是数组)
  • One by me about performance and safety using a generic wrapper
  • One on immutable arrays from the BCL team
  • Part 2 of Eric Lippert's blog series on variance in general (the series is mostly aimed at generics, but this part is on arrays)

这篇关于协变和逆变用C#数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆