Why do some C# lambda expressions compile to static methods?

后端 未结 5 426
误落风尘
误落风尘 2020-11-29 01:15

As you can see in the code below, I have declared an Action<> object as a variable.

Would anybody please let me know why this action method delega

5条回答
  •  时光取名叫无心
    2020-11-29 01:42

    Delegate caching behavior was changed in Roslyn. Previously, as stated, any lambda expression which didn't capture variables was compiled into a static method at the call site. Roslyn changed this behavior. Now, any lambda, which captures variables or not, is transformed into a display class:

    Given this example:

    public class C
    {
        public void M()
        {
            var x = 5;
            Action action = y => Console.WriteLine(y);
        }
    }
    

    Native compiler output:

    public class C
    {
        [CompilerGenerated]
        private static Action CS$<>9__CachedAnonymousMethodDelegate1;
        public void M()
        {
            if (C.CS$<>9__CachedAnonymousMethodDelegate1 == null)
            {
                C.CS$<>9__CachedAnonymousMethodDelegate1 = new Action(C.b__0);
            }
            Action arg_1D_0 = C.CS$<>9__CachedAnonymousMethodDelegate1;
        }
        [CompilerGenerated]
        private static void b__0(int y)
        {
            Console.WriteLine(y);
        }
    }
    

    Roslyn:

    public class C
    {
        [CompilerGenerated]
        private sealed class <>c__DisplayClass0
        {
            public static readonly C.<>c__DisplayClass0 CS$<>9__inst;
            public static Action CS$<>9__CachedAnonymousMethodDelegate2;
            static <>c__DisplayClass0()
            {
                // Note: this type is marked as 'beforefieldinit'.
                C.<>c__DisplayClass0.CS$<>9__inst = new C.<>c__DisplayClass0();
            }
            internal void b__1(int y)
            {
                Console.WriteLine(y);
            }
        }
        public void M()
        {
            Action arg_22_0;
            if (arg_22_0 = C.
                           <>c__DisplayClass0.CS$<>9__CachedAnonymousMethodDelegate2 == null)
            {
                C.<>c__DisplayClass0.CS$<>9__CachedAnonymousMethodDelegate2 =
              new Action(C.<>c__DisplayClass0.CS$<>9__inst.b__1);
            }
        }
    }
    

    Delegate caching behavior changes in Roslyn talks about why this change was made.

提交回复
热议问题