在阅读一本section http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29#Arrays在维基百科上一篇关于协变和逆变的文章中,我遇到了以下粗体句子:
首先考虑数组类型构造函数:来自类型Animal
我们可以制作类型Animal[]
(“动物阵列”)。我们是否应该将其视为
- 协变:a
Cat[]
is a Animal[]
- 逆变:a
Animal[]
is a Cat[]
- 或两者都不是(不变)?
如果我们希望避免类型错误,并且数组支持读取和写入元素,那么只有第三种选择是安全的。显然,并非每一个Animal[]
可以被视为一个Cat[]
,因为从数组中读取的客户端会期望一个 Cat,但是一个Animal[]
可能包含例如ADog
。所以逆变规则并不安全。
相反,一个Cat[]
不能被视为Animal[]
.应该总是可以放置一个Dog
into a Animal[]
。对于协变数组,这不能保证安全,因为后备存储实际上可能是猫的数组。所以协变规则也不安全——数组构造函数应该是不变的。请注意,这只是可变数组的问题;协变规则对于不可变(只读)数组是安全的。
我理解这个概念;我只想要一个example说明 C# 中如何“不能保证安全”。
这不安全在编译时。换句话说,有些代码根据语言规则是合法的,但在执行时失败,没有任何显式转换来给出“这可能会失败”的大警告信号。 CLR 确保只有有效的写入才能成功执行时间。例如:
string[] strings = new string[1];
object[] objects = strings;
objects[0] = new object();
这将引发异常(ArrayTypeMismatchException https://learn.microsoft.com/en-us/dotnet/api/system.arraytypemismatchexception) 在执行时。另一种选择是allow它在执行时,此时strings[0]
将是对非字符串对象的引用,这显然是不好的。
另请参阅最近的博客文章:
-
我的一份 https://codeblog.jonskeet.uk/2013/06/22/array-covariance-not-just-ugly-but-slow-too/关于使用通用包装器的性能和安全性
-
一是关于不可变数组 https://devblogs.microsoft.com/dotnet/please-welcome-immutablearrayt/来自 BCL 团队
-
Eric Lippert 关于一般方差的博客系列的第 2 部分 https://learn.microsoft.com/en-us/archive/blogs/ericlippert/covariance-and-contravariance-in-c-part-two-array-covariance(该系列主要针对泛型,但这部分是关于数组的)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)