Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the following example using covariance in delegates not compile?

Tags:

People also ask

What is delegate covariance?

C# Delegate Covariance allows us to call a method that has derived return type of the delegate signature return type. It means we can call a method that returns parent or child class object.

What is the difference between covariance and contravariance in delegates?

Covariance permits a method to have return type that is more derived than that defined in the delegate. Contravariance permits a method that has parameter types that are less derived than those in the delegate type.

Which delegates support covariance and contravariance in C#?

In . NET Framework 4 and later versions, C# supports covariance and contravariance in generic interfaces and delegates and allows for implicit conversion of generic type parameters.

What is the difference between covariance and contravariance?

Covariance permits a method to have a return type that is a subtype of the one defined in the delegate. Contravariance permits a method to have a parameter type that is a base type of the one defined in the delegate type.


I have defined the following delegate types. One returns a string, and one an object:

delegate object delobject();
delegate string delstring();

Now consider the following code:

delstring a = () => "foo";
delobject b = a; //Does not compile!

Why is the assignment not valid ?

I do not understand. A method which returns a string should be safely considered as a method which returns an object (since a string is an object).


In C# 4.0, the following example works. Instead of using delegates, I use the Func<TResult> generic type:

Func<string> a = () => "foo";
Func<object> b = a; //Perfectly legal, thanks to covariance in generics

Also: if I rewrote it that way, it works:

delobject b = () => a();

But this is not the same thing as what I wanted initially. Now I have created a new method which calls another one.

It is not just an assignment, as shown in this example:

delint a = () => 5;
delobject b = a; //Does not work, but this is OK, since "int" is a value type.
delobject b = () => a(); //This will box the integer to an object.