I recently started to think of this problem and I can't find the answer. The following code compiles and executes as expected
我最近开始思考这个问题,但我找不到答案。以下代码按照预期进行编译和执行
object[] test = new string[12];
However, I don't know why.
然而,我不知道为什么。
I mean, should we consider string[] as the derived class of object[]? I think in C#, every array is an instance of Array class. If Array is generic, it should be Array<T>
, and Array<string>
can be assigned to Array<object>
, it doesn't make sense. I remember only interface can use in/out keyword.
我的意思是,我们是否应该将string[]作为对象的派生类[]?我认为在c#中,每个数组都是数组类的实例。如果数组是泛型的,它应该是数组
And in Java, I'm not sure, but still feel weird. Why different types of references can be possibly assigned to each other when they don't have super-sub class relationship?
在Java中,我不确定,但仍然觉得奇怪。为什么不同类型的引用在没有超子类关系时可能被分配给对方?
Can somebody explain a little?
有人能解释一下吗?
Thanks a lot!
谢谢!
4 个解决方案
#1
5
It's because reference type arrays support covariance in both Java and C#. It also means that every write into a reference type array has to be checked at execution time, to make sure you don't write the wrong type of element into it :(
这是因为引用类型数组在Java和c#中都支持协方差。它还意味着在执行时必须检查每一次写入引用类型数组的操作,以确保不会将错误类型的元素写入其中:(
Don't forget that both Java and C# (and .NET in general) started off without generics. If they had had generics to start with, life could have been somewhat different.
不要忘记,Java和c#(以及。net)一开始都没有泛型。如果他们一开始就有了泛型,生活就会有些不同。
Note that both Java and C# support generic variance now, but in rather different ways. So for example in C# 4 you can write:
注意,现在Java和c#都支持泛型变量,但是方式不同。例如在c# 4中你可以这样写:
IEnumerable<string> strings = // Get some string sequence here
IEnumerable<object> objects = strings;
but you can't write
但是你不能写
IList<string> strings = // Get some string list here
// Compile-time error: IList<T> isn't covariant in T
IList<object> objects = strings;
This wouldn't be safe, because you can add to an IList<T>
as well as taking items from it.
这是不安全的,因为你可以添加到IList
This is a big topic - for more details, see Eric Lippert's blog series.
这是一个大话题——更多细节,请参阅Eric Lippert的博客系列。
#2
0
In C# there is (and always been) covariance of arrays of reference-types. It still is a string[]
, but you can legally cast it to an object[]
(and access values as you would expect).
在c#中,引用类型的数组有(而且一直有)协方差。它仍然是一个字符串[],但是您可以合法地将它转换为一个对象[](并访问您期望的值)。
But try putting in an int
(or any other non-string value) and you'll see that it still behaves appropriately (i.e. doesn't let you).
但是尝试输入int(或任何其他非字符串值),您将看到它仍然是适当的(即不让您)。
#3
0
This is because object is the parent (or the superclass) for all other classes. Search for boxing/ unboxing for more data.
这是因为对象是所有其他类的父类(或超类)。寻找更多数据的拳击/拳击。
#4
0
Since all the really smart guys are talking about covariance and contravariance and I couldn't for the life of me explain (or understand) this stuff, listen to Eric Lippert:
因为所有真正聪明的人都在讨论协变和逆变,我一辈子都没办法解释(或理解)这个东西,听埃里克·利伯特说:
Covariance and Contravariance FAQ
协变和逆变的常见问题
#1
5
It's because reference type arrays support covariance in both Java and C#. It also means that every write into a reference type array has to be checked at execution time, to make sure you don't write the wrong type of element into it :(
这是因为引用类型数组在Java和c#中都支持协方差。它还意味着在执行时必须检查每一次写入引用类型数组的操作,以确保不会将错误类型的元素写入其中:(
Don't forget that both Java and C# (and .NET in general) started off without generics. If they had had generics to start with, life could have been somewhat different.
不要忘记,Java和c#(以及。net)一开始都没有泛型。如果他们一开始就有了泛型,生活就会有些不同。
Note that both Java and C# support generic variance now, but in rather different ways. So for example in C# 4 you can write:
注意,现在Java和c#都支持泛型变量,但是方式不同。例如在c# 4中你可以这样写:
IEnumerable<string> strings = // Get some string sequence here
IEnumerable<object> objects = strings;
but you can't write
但是你不能写
IList<string> strings = // Get some string list here
// Compile-time error: IList<T> isn't covariant in T
IList<object> objects = strings;
This wouldn't be safe, because you can add to an IList<T>
as well as taking items from it.
这是不安全的,因为你可以添加到IList
This is a big topic - for more details, see Eric Lippert's blog series.
这是一个大话题——更多细节,请参阅Eric Lippert的博客系列。
#2
0
In C# there is (and always been) covariance of arrays of reference-types. It still is a string[]
, but you can legally cast it to an object[]
(and access values as you would expect).
在c#中,引用类型的数组有(而且一直有)协方差。它仍然是一个字符串[],但是您可以合法地将它转换为一个对象[](并访问您期望的值)。
But try putting in an int
(or any other non-string value) and you'll see that it still behaves appropriately (i.e. doesn't let you).
但是尝试输入int(或任何其他非字符串值),您将看到它仍然是适当的(即不让您)。
#3
0
This is because object is the parent (or the superclass) for all other classes. Search for boxing/ unboxing for more data.
这是因为对象是所有其他类的父类(或超类)。寻找更多数据的拳击/拳击。
#4
0
Since all the really smart guys are talking about covariance and contravariance and I couldn't for the life of me explain (or understand) this stuff, listen to Eric Lippert:
因为所有真正聪明的人都在讨论协变和逆变,我一辈子都没办法解释(或理解)这个东西,听埃里克·利伯特说:
Covariance and Contravariance FAQ
协变和逆变的常见问题