Why is array co-variance considered so horrible?

In .NET reference type arrays are co-variant. This is considered a mistake.

Type-safety breaking array covariance is considered by some people to be a mistake in the design of .NET. It is not so considered by all people. I do not consider it to be a mistake; I consider it to be an unfortunate choice. All design processes involve choices between undesirable alternatives. In this case, the choice was between adding an unsafe implicit conversion that imposes a run-time cost on all array writes, or building a type system that could not easily implement the Java type system. That’s a tough choice and the designers of the type system made the best choice they could with the information they had.

That explanation of course is mere question begging; isn’t it then simply the case that the designers of Java made a mistake? Possibly yes, possibly no; likely the designers of Java also faced tradeoffs in the design of their type system. Any experts on the history of the development of the Java type system who would like to chime in here on what those tradeoffs were, I’d be interested to know.

I, with the benefit of ten years of hindsight, personally would have preferred it if the designers of the .NET type system had chosen to eschew safety-breaking array covariance. But that doesn’t make that choice a “mistake”, it just makes it somewhat unfortunate.

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

Yes. It means that code that looks like it ought to always run successfully can fail at runtime. And it means that correct code has a performance penalty imposed upon it.

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?

This is a strange question. The question is essentially “I have two guns already with which I can shoot myself in the foot, so why is it considered harmful for me to shoot myself in the foot with a third?”

The existence of two dangerous patterns that violate type safety does not make a third such pattern any less dangerous.

Language and runtime features that violate type safety are there for those times when you absolutely positively know that what you are doing is safe, even if the compiler doesn’t know it. If you don’t understand those features well enough to use them safely then do not use them.

Leave a Comment