【问题标题】:How are lambdas resolved in the .NET framework?.NET 框架中如何解析 lambda?
【发布时间】:2015-05-06 14:58:20
【问题描述】:

例如,您可以在 Visual Studio 2010 中使用 lambda 表达式,但仍以 .NET 2.0 为目标。

编译器如何解析 lambda 表达式以使用不包含此功能的旧框架?

【问题讨论】:

  • 他们是匿名代表。代表从 1.0 开始就在那里,“匿名”只是意味着“名称由编译器分配”
  • @dman2306 不,lambda 不会编译成匿名方法。这两个功能都被编译成传统代码。
  • @dman2306 VB.NET 不包括匿名委托。
  • 简单地说,lambda 表达式是一种语言特性,而不是运行时特性。编译器生成的 MSIL 不需要运行时的任何“新”(即晚于 .NET 2.0)特性。
  • @dman2306 从技术上讲,“匿名代表”这个短语并不合理。大概您指的是构造:delegate { someMethod(); }。那是一个匿名方法,它构造一个委托。可悲的是,这里使用delegate 关键字会引起一些混乱。匿名方法和 lambda 以及方法组和其他一些可能性都可用于创建委托,委托只是另一种类型的对象,恰好代表了在实例上调用方法的能力。

标签: c# .net vb.net lambda


【解决方案1】:

Lambda 不依赖任何较新的框架功能。归根结底,一个 lambda 只需要能够创建一个包含字段、方法和构造函数的新类,所有这些都在 1.0 运行时/框架中可用。

以下代码:

int value = 42;
MyDelegate f = () => value;

将转化为新的命名类型:

public class SomeRandomCompilerGeneratedNameGoesHere
{
    public int value;
    public int SomeGeneratedMethodName()
    {
        //the content of the anonymous method goes here
        return value;
    }
}

并且会这样使用:

var closureClass = new SomeRandomCompilerGeneratedNameGoesHere();
closureClass.value = 42;
MyDelegate f = closureClass.SomeGeneratedMethodName;

现在,有些情况不需要所有这些;如果没有封闭的值,这些步骤中的一些可以兴高采烈,并添加优化(即方法可以设为静态,以避免创建对象实例),但此处显示的转换能够映射任何有效的 C# lambda ,如您所见,它转换成的代码即使在 C# 1.0 中也是有效的。

【讨论】:

    【解决方案2】:

    Lambda 表达式是编译器功能。您不需要框架或 CLR 支持。

    编译器将为您创建一个方法并为您执行隐式委托转换和所有这些工作。您所需要的只是实现该功能的新编译器。

    大多数语言功能都与任何版本的 .Net 框架无关。其中一些只是工作;其中一些可以使用一些技巧进行调整。

    例如:隐式委托转换、集合初始化器、对象初始化器将按原样工作。扩展方法可以与一些技巧一起使用。

    有关详细信息,请参阅 Jon's article,“在 .NET 2.0 和 3.0 中使用 C# 3”部分。

    FWIW,仅使用相同的概念 BCL.Async 库在与 .net 4.5 一起发布的 .Net 4.0 中启用 async-await 功能。

    【讨论】:

      猜你喜欢
      • 2011-06-28
      • 1970-01-01
      • 2022-01-28
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      相关资源
      最近更新 更多