首页 > 解决方案 > 编译器为纯静态方法体生成类

问题描述

考虑这个 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 基本上是静态的,它生成了一个类,而其他的则有一个生成的方法。为什么编译器在这种情况下不生成静态方法?

当您添加这些行时,它变得更加奇怪

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

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

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

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

然后它将每个 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 进行特殊处理的原因是什么?

标签: c#lambdaroslyn

解决方案


推荐阅读