tags:

views:

125

answers:

4

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!

+5  A: 

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.

Jon Skeet
Thank you. It explains a lot.
LLS
A: 

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).

Marc Gravell
Thanks. I start to understand it now.
LLS
A: 

This is because object is the parent (or the superclass) for all other classes. Search for boxing/ unboxing for more data.

rursw1
Covariance is the relevant mechanism here.
Alkaline
A: 

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

Daren Thomas
This post really answers my question in detail (at least C# part). Thanks a lot.
LLS