Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
531 views
in Technique[技术] by (71.8m points)

c# - Why is array co-variance considered so horrible?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...