Delegate Covariance and Comparison

Consider the following code snippet

namespace ConsoleApplication1 { public delegate TResult Function<in T, out TResult>(T args); class Program { static void Main(string[] args) { Program pg =new Program(); Function<Object, DerivedClass> fn1 = null; Function<String, BaseClass> fn2 = null; fn1 = new Function<object, DerivedClass>(pg.myCheckFuntion) fn2=fn1; fn2("");// calls myCheckFuntion(Object a) pg.myCheckFuntion("Hello"); //calls myCheckFuntion(String a) } public DerivedClass myCheckFuntion(Object a) { return new DerivedClass(); } public DerivedClass myCheckFuntion(String a) { return new DerivedClass(); } } 

why calling a delegate and calling a normal method call different methods.

+7
source share
3 answers

The delegate is bound to myCheckFuntion(Object) at compile time - you tell it to find a method that accepts Object . This binding is only to one method - it does not execute overload resolution at run time based on the actual type of the argument.

When you call pg.myCheckFuntion("Hello") , which will bind to myCheckFuntion(String) at compile time because "Hello" is a string, and converting from string to string is preferable to converting from string to object in overload resolution.

Please note that if you write:

 object text = "Hello"; pg.myCheckFuntion(text); 

then it will call myCheckFuntion(Object) .

+8
source

fn2 calls myCheckFuntion(Object a) because of its declaration:

 fn1 = new Function<object, DerivedClass>(pg.myCheckFuntion) fn2 = fn1; // here you copy the reference 

pg.myCheckFuntion("Hello"); calls myCheckFuntion(Object a) , because String more restrictive type than object .

if you added a line to object :

 pg.myCheckFuntion((object)"Hello"); 

It is called by another method.

+2
source

The delegate object itself still points to only one function, not a whole series of functions. The variance co (ntra) allows you to specify it in a larger domain of function types. In the same way, you can assign all kinds of values ​​to a variable of type object , but less than a variable of type string . However, the variable will still have only one actual type and one actual value at any given time.

+1
source

All Articles