C#中的闭包是否会导致生成的IL代码膨胀?有人告诉我要避免使用带有闭包变量的lambda表达式,因为它们会在对象文件中生成隐藏的类,可以存储lambda表达式的上下文。对于每个带有闭包变量的lambda表达式都会生成一个类。这是否属实?或者编译器是否重用现有的类,如Tuple或某些内部类?
只有在需要时,才会生成额外的类 - 当您捕获除this
之外的变量时。然而,在大多数情况下,这并不是代码膨胀 - 它是必要的,以使委托按您需要的方式工作。
在某些情况下,您可以自己编写更有效率的代码,但通常为了获得具有相同效果的委托,您将编写与编译器为您生成的代码类似但更难读的代码。
大多数情况下,您不应该担心这种"膨胀" - 首先避免为性能微调 - 优化可读性,并测量性能而不是猜测它。然后,当您证明它值得时,您可以攻击真正重要的代码部分,也许会为性能牺牲一点可读性。
(编写现代 C# 并故意避免使用 lambda 表达式就像是绑着一只手编程。如果建议您的人担心闭包的"膨胀",您可能会向他展示在 C# 5 中为异步/等待生成的状态机,从而使他感到心脏病发作...)
是的,这是真的。
需要跟踪变量的类必须存在。一个Tuple
或内部类无法为所有可能的代码路径做到这一点,因此对于每个lambda/closure需要在IL中特别生成这样的状态机。
是否对您的应用程序造成问题取决于您自己来确定。
using
语句呢?它们都会产生生成的代码 - 你会称它们为臃肿吗? - Oded