19

因此,每次我在一个我不太正确的方法中编写了一个 lambda 表达式或匿名方法时,我都不得不重新编译并重新启动整个应用程序或单元测试框架以修复它。这很烦人,而且我最终浪费的时间比我最初使用这些构造所节省的时间还要多。很糟糕,如果可以的话,我会尽量远离它们,尽管 Linq 和 lambdas 是我最喜欢的 C# 功能之一。

我想有一个很好的技术原因为什么会这样,也许有人知道?此外,有谁知道它是否会在 VS2010 中修复?

谢谢。

4

4 回答 4

20

是的,你不能这样做是有充分理由的。原因很简单,就是成本。在 C#(或 VB)中启用此功能的成本非常高。

编辑 lambda 函数是一类 ENC 问题的特定情况,这些问题很难用当前的 ENC (Edit'n'Continue) 架构解决。也就是说,很难对 ENC 执行以下操作之一的任何方法进行 ENC:-

  1. 以类的形式生成元数据
  2. 编辑或生成泛型方法

第一个问题更多是逻辑约束,但它也遇到了 ENC 架构中的一些限制。即问题是生成第一类并不是非常困难。麻烦的是在第二次编辑之后生成类。ENC 引擎必须开始跟踪符号表,不仅是实时代码,还包括生成的类。通常这不是那么糟糕,但是当生成的类的形状基于使用它的上下文时,这变得越来越困难(就像由于闭包而使用 lambdas 的情况一样)。更重要的是,您如何解决与流程中已经存在的类实例的差异?

第二个问题是 CLR ENC 架构中的严格限制。C#(或 VB)无法解决此问题。

不幸的是,Lambdas 解决了这两个问题。简短的版本是对 lambda 进行 ENC 处理涉及现有类的大量突变(可能是也可能不是从其他 ENC 生成的)。最大的问题在于解决新代码与当前进程空间中存在的现有闭包实例之间的差异。此外,与其他代码相比,lambda 更倾向于使用泛型并遇到问题 #2。

对于正常的 SO 答案,细节非常繁琐,而且有点过于复杂。我考虑过写一篇关于这个主题的长篇博文。如果我解决它,我会将它链接回这个特定的答案。

于 2009-02-24T15:15:49.777 回答
1

根据支持的代码更改列表,您不能将字段添加到现有类型。匿名方法被编译成奇怪命名的类(kinda <>_c__DisplayClass1),它们就是:类型。即使您对匿名方法的修改可能不包括更改封闭变量集(添加这些变量会改变现有类的字段),我想这就是无法修改匿名方法的原因。

于 2009-02-24T14:56:04.300 回答
1

VB 部分支持此功能但 C# 不支持此功能有点遗憾:http: //msdn.microsoft.com/en-us/library/bb385795.aspx

在 C# 中实现相同的行为将使包含 lambda 表达式的函数的痛苦程度降低 80%,在这种情况下,我们不需要修改 lambda 表达式或任何依赖于它们的表达式,而且可能不需要“巨额成本”。

于 2011-05-25T16:33:55.963 回答
0

如果那样的话,重新启动一个单元测试应该需要几秒钟。老实说,我从不喜欢“编辑并继续”模型——你应该总是从头开始重新运行 IMO,以防万一执行中途的更改会影响之前运行的代码。鉴于此,您最好使用可以快速运行的单元测试。如果您的个人单元测试开始时间难以忍受,那么您应该考虑解决这个问题。

编辑:至于为什么它不起作用-您可能会发现它适用于某些 lambda,但不适用于其他 lambda。不捕获任何变量(包括this)的 Lambda 表达式被缓存在私有静态变量中,因此只创建了一个委托实例。更改代码意味着重新初始化该变量,这可能会产生我怀疑的有趣副作用。

于 2009-02-24T14:50:16.000 回答