Alex Rivera | Logout

Why is array co-variance considered so horrible?

Asked 2010-11-30T19:05:57.663
14

In .NET reference type arrays are co-variant. This is considered a mistake. However, I don't see why this is so bad consider the following code:

string[] strings = new []{"Hey there"};
object[] objects = strings;
objects[0] = new object();

Oh ho, this compiles and will fail at runtime. As we tried to stick an object into a string[]. Okay, I agree that stinks, but a T[] extends Array and also implements IList (and IList<T>, I wonder if it implements IList<BaseType>...>. Both Array and IList allow us to make the same horrid mistake.

string[] strings = new []{"Hey there"};
Array objects = strings;
objects.SetValue(new object(),new[]{0});

IList version

string[] strings = new []{"Hey there"};
IList objects = strings;
objects[0] = new object();

The T[] classes are generated by the CLR, and have to include a type check on the equivalent of the set_Item method (arrays don't actually have one).

Is the concern that setting to a T[] has to do the type check at runtime (which violates the type-safety you expect at compile time)? Why is it considered harmful for arrays to exhibit this property when there are equivalent means to shoot yourself in the foot through the provided means above?

Edit
Report

1 Answer

2

I think your note about IList points to something worth considering here.

It is pretty useful that IList is implemented by arrays. It's also useful that there other collections that implement it.

Now, these days, indeed for the last 5 years, we have often found it more useful (or equally useful and safer) to deal with IList<T>.

Prior to .NET2.0 though, we didn't have IList<T>, we only had IList. Quite a few cases where one might move between arrays and other collections were fiddlier (at best) prior to generics which in many cases now let us move between typed collections and typed arrays with greater confidence.

As such, the arguments in favour of covariant arrays were greater when the relevant decisions were made, than they are now. And that they build on similar decisions in Java when it didn't have generics only adds to this fact.

answered 2010-12-01T00:21:12.673

Your Answer