Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are all Delegate types incompatible with each other?

Tags:

c#

In C# all delegate types are incompatible with one another, even if they have the same signature. As an example:

delegate void D1();
delegate void D2();

D1 d1 = MethodGroup;
D2 d2 = d1;                           // compile time error
D2 d2 = new D2 (d1);                  // you need to do this instead

What is the reasoning behind this behaviour and language design decision.

like image 334
AlexC Avatar asked Jun 20 '13 13:06

AlexC


People also ask

What will happen if a delegate has a non void return type?

When the return type is not void as above in my case it is int. Methods with Int return types are added to the delegate instance and will be executed as per the addition sequence but the variable that is holding the return type value will have the value return from the method that is executed at the end.

Can a delegate point to more than one method?

A delegate is a type safe and object oriented object that can point to another method or multiple methods which can then be invoked later.

Are delegates type-safe?

Delegates are not type-safe. Delegate is a user-defined type. Only one method can be bound with one delegate object. Delegates can be used to implement callback notification.


2 Answers

In C# all delegate types are incompatible with one another, even if they have the same signature. What is the reasoning behind this behaviour and language design decision?

First off, I think that it is fair to say that many of the runtime and language designers regret this decision. Structural typing on delegates -- that is, matching by signature -- is a frequently requested feature and it just seems strange that Func<int, bool> and Predicate<int> can't be freely assigned to each other.

The reasoning behind the decision as I understand it -- and I hasten to add that this decision was made about six years before I started on the C# team -- is that the expectation was that there would be delegate types with semantics. You want this to be a type error:

AnyFunction<int, int> af = x=> { Console.WriteLine(x); return x + y; };
PureFunction<int, int> pf = af;

A "pure" function is a function which produces and consumes no side effects, consumes no information outside of its arguments, and returns a consistent value when given the same arguments. Clearly af fails at least two of those, and so should not be assignable to pf as an implicit conversion.

But semantics-laden delegate types never happened, so it's a bit of a misfeature now.

like image 167
Eric Lippert Avatar answered Oct 12 '22 13:10

Eric Lippert


Basically because the compiler makes two classes for you. The same reason you can't do:

class A {}
class B {}

void Main()
{
    A a = new A();
    B b = a;
}

For example, the following code

void Main() {}

delegate void D();
class C {}

The IL code is:

D.Invoke:

D.BeginInvoke:

D.EndInvoke:

D..ctor:

C..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret         
like image 21
dav_i Avatar answered Oct 12 '22 15:10

dav_i