百科问答小站 logo
百科问答小站 font logo



C#的Lambda表达式是动态生成的吗? 第1页

  

user avatar   rednaxelafx 网友的相关建议: 
      

C#里lambda表达式的解糖方式,取决于lambda捕获的东西有多少,有若干不同的方式。

针对题主的例子,假如有这样的代码:

       using System; using System.Collections.Concurrent;       public class Program {  public static void Foo<TKey, TVal>(ConcurrentDictionary<TKey, TVal> concDict, TKey key, TVal newValue) {   concDict.AddOrUpdate(key, newValue, (cKey, oldValue) => newValue);  } }      

C#编译器会在编译时将它解语法糖,生成一些额外的代码。由于这里的lambda捕获了一个方法参数(局部变量的话也一样),这里选择的解糖方式是:

  • 生成一个新的“匿名”类来持有被捕获的变量。被捕获的变量就变成了这个类的成员变量。这叫做“提升”(hoisting)。然后在所有原本访问那个被捕获变量的地方,都会被改写为访问这个提升后的成员变量。这样就实现了“引用捕获”(capture-by-reference)的语义;
  • 将lambda表达式的函数体解糖为上述新生成的类的成员方法。

于是解糖后,这个例子的代码会变成下面这样:

(下面的代码里名字都是csc.exe实际生成的样子。它故意要用一些C#不允许用做标识符的符号作为名字的一部分,避免跟用户写的代码里的标识符冲突)

       using System; using System.Collections.Concurrent;       public class Program {  // generated class for captured arguments/local variables  private class <>c__DisplayClass1`2'<TKey,TVal> {   public TVal newValue;   public TVal <Foo>b__0(TKey cKey, TVal oldValue) {    return this.newValue;   }  }   public static void Foo<TKey, TVal>(ConcurrentDictionary<TKey, TVal> concDict, TKey key, TVal newValue) {   var captures = new <>c__DisplayClass1`2'<TKey,TVal>();   captures.newValue = newValue;   var lambda = new Func3<TKey, TVal, TVal>(captures.<Foo>b__0);   concDict.AddOrUpdate(key, captures.newValue, lambda);  } }      

就这样而已。很简单对不对?

数据是动态确定的,代码是静态确定的。可以看到Foo()的参数newValue是动态被捕获到captures里的,但captures的代码是静态生成好的。

顺带放个老传送门:

关于对象与闭包的关系的一个有趣小故事

,留意那帖下面的评论区的讨论。

然后这个传送门:

JVM的规范中允许编程语言语义中创建闭包(closure)吗? - RednaxelaFX 的回答 - 知乎



  

相关话题

  C++中lambda表达式中捕获的值变量存在哪? 
  「Lambda calculus」翻译为「Lambda 表达式」是否妥当? 
  Java 8的新特性lambda表达式是否比匿名内部类具有更好的可读性? 
  C#的Lambda表达式是动态生成的吗? 
  Java 8的新特性lambda表达式是否比匿名内部类具有更好的可读性? 
  C#的Lambda表达式是动态生成的吗? 
  Java 8的新特性lambda表达式是否比匿名内部类具有更好的可读性? 
  C#的Lambda表达式是动态生成的吗? 
  Java 8的新特性lambda表达式是否比匿名内部类具有更好的可读性? 
  Java 8的新特性lambda表达式是否比匿名内部类具有更好的可读性? 

前一个讨论
知乎上有哪些著名的“计算机科学”领域的“民科”?
下一个讨论
正确的小写字母F占几格?





© 2024-12-26 - tinynew.org. All Rights Reserved.
© 2024-12-26 - tinynew.org. 保留所有权利