C# compiler oddity with delegate constructors

后端 未结 3 1099
孤城傲影
孤城傲影 2020-12-31 16:31

Based on the following question, I found some odd behaviour of the c# compiler.

The following is valid C#:

static void K() {}

static void Main()
{
          


        
3条回答
  •  旧巷少年郎
    2020-12-31 16:58

    The spec (section 7.6.10.5) says:

    • The new delegate instance is initialized with the same invocation list as the delegate instance given by E.

    Now suppose the compiler translated it to something similar to your suggestion of:

    new Action( a.Target, a.Method)
    

    That would only ever create a delegate with an invocation list of a single method call. For a multi-cast delegate, it would violate the spec.

    Sample code:

    using System;
    
    class Program
    {
        static void Main(string[] args)
        {
            Action first = () => Console.WriteLine("First");
            Action second = () => Console.WriteLine("Second");
    
            Action both = first + second;
            Action wrapped1 =
                (Action) Delegate.CreateDelegate(typeof(Action),
                                                 both.Target, both.Method);
            Action wrapped2 = new Action(both);
    
            Console.WriteLine("Calling wrapped1:");
            wrapped1();
    
            Console.WriteLine("Calling wrapped2:");
            wrapped2();
        }
    }
    

    Output:

    Calling wrapped1:
    Second
    Calling wrapped2:
    First
    Second
    

    As you can see, the real behaviour of the compiler matches the spec - your suggested behaviour doesn't.

    This is partly due to the somewhat odd "sometimes single-cast, sometimes multi-cast" nature of Delegate, of course...

提交回复
热议问题