编译器为纯静态方法主体生成类

时间:2019-03-13 20:19:17

标签: c# lambda roslyn

考虑此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;
    }
}

请注意,第一个lambda基本是静态的,它会生成一个类,而其他lambda都有一个生成的方法。 在这种情况下,编译器为什么不生成静态方法?

添加这些行会变得更加奇怪

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

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

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

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

然后它将每个lamnbda生成为一个类,但是纯静态的lamnbda仍然是一个异常,并且具有自己的类。

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);
}

对纯静态lambda进行特殊处理的原因是什么?

0 个答案:

没有答案