Компилятор генерирует класс для чисто статического тела метода - PullRequest
1 голос
/ 13 марта 2019

Рассмотрим этот код C #

using System;

public class _
{
    private static int STAT = 9;

    private int INST = 7;

    private void Run(int arg)
    {
        X(() => STAT * STAT);

        X(() => STAT * INST);

        X(() => INST * STAT);

        X(() => INST * INST);
    }

    public void X<T>(Func<T> getValue) {}
}

Согласно https://sharplab.io/ компилятор генерирует следующий код (сокращенный до соответствующих частей).

    [Serializable]
    [CompilerGenerated]
    private sealed class <>c
    {
        public static readonly <>c <>9 = new <>c();

        public static Func<int> <>9__2_0;

        internal int <Run>b__2_0()
        {
            return STAT * STAT;
        }
    }

    private void Run(int arg)
    {
        X(<>c.<>9__2_0 ?? (<>c.<>9__2_0 = <>c.<>9.<Run>b__2_0));
        X(<Run>b__2_1);
        X(<Run>b__2_2);
        X(<Run>b__2_3);
    }

    [CompilerGenerated]
    private int <Run>b__2_1()
    {
        return STAT * INST;
    }

    [CompilerGenerated]
    private int <Run>b__2_2()
    {
        return INST * STAT;
    }

    [CompilerGenerated]
    private int <Run>b__2_3()
    {
        return INST * INST;
    }
}

Обратите внимание, что первая лямбда, которая в основном статична, генерирует класс, в то время как другие имеют сгенерированный метод. Почему в этом случае компилятор не генерирует статический метод?

Становится еще страннее, когда вы добавляете эти строки

X(() => arg * STAT * STAT);

X(() => arg * STAT * INST);

X(() => arg * INST * STAT);

X(() => arg * INST * INST);

Затем он генерирует каждую лямбду в один класс, но чисто статический класс все еще делает исключение и имеет свой собственный класс.

private void Run(int arg)
{
    <>c__DisplayClass2_0 <>c__DisplayClass2_ = new <>c__DisplayClass2_0();
    <>c__DisplayClass2_.<>4__this = this;
    <>c__DisplayClass2_.arg = arg;
    X(<>c.<>9__2_0 ?? (<>c.<>9__2_0 = <>c.<>9.<Run>b__2_0));
    X(<>c__DisplayClass2_.<Run>b__1);
    X(<>c__DisplayClass2_.<Run>b__2);
    X(<>c__DisplayClass2_.<Run>b__3);
    X(<>c__DisplayClass2_.<Run>b__4);
    X(<>c__DisplayClass2_.<Run>b__5);
    X(<>c__DisplayClass2_.<Run>b__6);
    X(<>c__DisplayClass2_.<Run>b__7);
}

В чем причина такого особого отношения к чистой статической лямбде?

...