为什么一些C#lambda表达式要编译成静态方法?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (7)

正如您在下面的代码中所看到的,我已经声明了Action<>对象作为变量。

请让我知道为什么这个动作方法委托的行为像一个静态的方法?

为什么它会返回true

代码:

public static void Main(string[] args)
{
    Action<string> actionMethod = s => { Console.WriteLine("My Name is " + s); };

    Console.WriteLine(actionMethod.Method.IsStatic);

    Console.Read();
}

输出:

提问于
用户回答回答于

这很可能是因为没有闭包,例如:

int age = 25;
Action<string> withClosure = s => Console.WriteLine("My name is {0} and I am {1} years old", s, age);
Action<string> withoutClosure = s => Console.WriteLine("My name is {0}", s);
Console.WriteLine(withClosure.Method.IsStatic);
Console.WriteLine(withoutClosure.Method.IsStatic);

这将输出falsewithClosuretruewithoutClosure

当您使用lambda表达式时,编译器会创建一个小类来包含您的方法,这将编译如下(实际实现很可能略有变化):

private class <Main>b__0
{
    public int age;
    public void withClosure(string s)
    {
        Console.WriteLine("My name is {0} and I am {1} years old", s, age)
    }
}

private static class <Main>b__1
{
    public static void withoutClosure(string s)
    {
        Console.WriteLine("My name is {0}", s)
    }
}

public static void Main()
{
    var b__0 = new <Main>b__0();
    b__0.age = 25;
    Action<string> withClosure = b__0.withClosure;
    Action<string> withoutClosure = <Main>b__1.withoutClosure;
    Console.WriteLine(withClosure.Method.IsStatic);
    Console.WriteLine(withoutClosure.Method.IsStatic);
}

您可以看到结果Action<string>实例实际上指向这些生成的类上的方法。

用户回答回答于

“action method”是静态的,只是作为实现的一个副作用。这是匿名方法没有捕获变量的情况。由于没有捕获的变量,因此除了局部变量外,该方法没有额外的生存期要求。如果它引用了其他局部变量,则其生存期将扩展到其他变量的生存期(请参阅秒)。

请注意,C#规范只讨论将匿名方法转换为“表达式树”,而不是“匿名类”。虽然表达式树可以表示为额外的C#类,例如,在Microsoft编译器中,但这个实现并不是必需的(正如SEC所承认的那样)。

扫码关注云+社区