Why are all Delegate types incompatible with each other?

后端 未结 3 1628
迷失自我
迷失自我 2021-02-13 14:02

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          


        
相关标签:
3条回答
  • 2021-02-13 14:39

    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         
    
    0 讨论(0)
  • 2021-02-13 14:50

    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.

    0 讨论(0)
  • 2021-02-13 14:51

    Delegate is nothing but just another type. They are incompatible for the same reason class A {} and class B {} would be incompatible.

    delegate void D1();
    

    Will approximately compile to something like:

    class D1 : MulticastDelegate { .... } 
    
    0 讨论(0)
提交回复
热议问题