4

c# 中的闭包会导致生成的 il 中的代码膨胀吗?我被告知要避免使用带有闭包变量的 lambda,因为它们会在可以存储 lambda 上下文的目标文件中生成隐藏类。每个具有封闭变量的 lambda 的类。这是真的?或者编译器是否重用了一个现有的类,比如 Tuple 或一些内部类?

4

2 回答 2

17

额外的类仅在需要时生成——当您捕获除this. 但是,在大多数情况下,这并不是真正的代码膨胀——为了使委托按照您需要的方式工作,这是必要的。

某些情况下,您可以自己编写更高效的代码,但通常要获得具有相同效果的委托,您最终会编写与编译器为您生成的代码相似的代码……但阅读难度要大得多。

大多数时候你不应该担心这种“膨胀”——从一开始就避免对性能进行微优化——优化可读性,并测量性能而不是猜测它。然后,您可以攻击真正重要的代码位,并且当您证明这是值得的时,可能会牺牲一些可读性来提高性能。

(编写现代 C# 并故意避免使用 lambda 表达式就像试图用一只手绑在背后编码。如果建议您的人担心闭包的“膨胀”,您可能会通过向他展示状态来让他心脏病发作在 C# 5 中为 async/await 生成的机器...)

于 2012-05-13T18:20:32.940 回答
4

是的,这是真的。

需要存在一个跟踪变量的类。一个Tuple或内部类将无法对所有可能的代码路径执行此操作,因此需要在 IL 中专门为每个 lambda/closure 生成这样的状态机。

这是否是您的应用程序的问题由您确定。

于 2012-05-13T18:13:37.363 回答