Reputation: 2228
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.
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?
Can somebody explain a little?
Thanks a lot!
Upvotes: 2
Views: 455
Reputation: 70334
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
Upvotes: 0
Reputation: 5522
This is because object is the parent (or the superclass) for all other classes. Search for boxing/ unboxing for more data.
Upvotes: 0
Reputation: 1063198
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).
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).
Upvotes: 0
Reputation: 1501626
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 :(
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.
Note that both Java and C# support generic variance now, but in rather different ways. So for example in C# 4 you can write:
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.
This is a big topic - for more details, see Eric Lippert's blog series.
Upvotes: 5