c#中的闭包会导致生成的il中的代码膨胀吗?我被告知要避免使用闭包变量的lambdas,因为它们在目标文件中生成隐藏类,可以存储lambda的上下文。每个具有闭合变量的lambda的类。这是真的?或者编译器是否重用现有的类,如Tuple或一些内部类?
答案 0 :(得分:16)
只有在需要时才会生成额外的类 - 当您捕获this
以外的变量时。但是,在大多数情况下,这并不是真正的代码膨胀 - 它是必要的,以便使委托以您需要的方式工作。
在某些情况下,您可以自己编写更高效的代码,但通常为了获得具有相同效果的委托,您最终会编写与编译器为您生成的代码类似的代码......但更难阅读。
大多数时候你不应该担心这种“臃肿” - 避免微观优化性能开始 - 优化可读性,衡量性能而不是猜测它。然后你就可以攻击那些真正重要的代码,当你证明它是值得的时候,可能会牺牲一些可读性来获得性能。
(编写现代C#并故意避免使用lambda表达式就像试图用一只手绑在背后编码。如果建议你的人担心关闭的“膨胀”,你可能会通过显示给他一个心脏病发作他是在C#5中为async / await生成的状态机...)
答案 1 :(得分:4)
是的,这是真的。
跟踪变量的类需要存在。 Tuple
或内部类不能为所有可能的代码路径执行此操作,因此需要在IL中专门为每个lambda /闭包生成这样的状态机。
这是否适合您的应用程序是您可以确定的。