简体   繁体   中英

Generic delegate cannot have contravariant return type

A few days ago I started reading a C# manual. To this day, I've understood most of the concepts that were introduced pretty clearly except for this one thing:

delegate T TestDelegate<in T>();

This line of code doesn't even compile and I know that it is because the return type cannot be contravariant, I just don't understand WHY it can't be so.

Theodoros's answer is correct. A way I like to think about this question is to ask myself "suppose this were legal; what could go wrong?"

delegate T D<in T>(); // Suppose this were legal.
class Animal {}
class Tiger : Animal {}
class Giraffe : Animal {} // Plainly all these are legal.
...
D<Animal> da = () => new Tiger(); // A tiger is an animal, so this must be legal.
D<Giraffe> dg = da; // This is legal because T is declared contravariant in D.
Giraffe g = dg(); // This is legal, because dg returns a giraffe.
// Except that it actually returns a tiger, and now we have a tiger in
// a variable of type giraffe.

Every line in that little program fragment is obviously correct except for the first one. The program is not type safe and therefore must be illegal. Therefore we must conclude that the first line is the one which must be illegal, and it is.

A generic type parameter is contravariant if the declaring type becomes more general as the type argument becomes more specific , and vice versa. In other words, the delegate's generality runs in the opposite direction (contra) to that of the type parameter.

From the .NET class hierarchy, we know that a string is a special kind of object .

But TestDelegate<T> is a type for functions that promise to return a T . Are functions that return an object a special case of functions that promise to return a string ? Or are functions that return a string a special case of functions that promise to return an object ?

Clearly the latter is the case, which is why T can only be covariant , meaning that its generality goes the same direction as the declaring type. (Or invariant, but we don't care about that here.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM