为什么我不能在debugging器中编辑一个包含匿名方法的方法?

所以,每次我写一个lambdaexpression式或者匿名方法的时候,我都不太清楚 ,我不得不重新编译并重新启动整个应用程序或者unit testing框架来修复它。 这是非常烦人的,而最终我浪费的时间比通过使用这些结构所节省的时间更多。 尽pipeLinq和lambdas是我最喜欢的C#特性之一,但是如果可以的话,我尽量远离它们,这太糟糕了。

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

谢谢。

是的,有一个很好的理由,为什么你不能这样做。 简单的原因是成本。 在C#(或VB)中启用此function的成本非常高。

编辑一个lambda函数是ENC问题类的一个特例,在当前的ENC(Edit'n'Continue)体系结构中很难解决。 也就是说,对ENC执行以下操作之一的任何方法都很难ENC: –

  1. 以类的forms生成元数据
  2. 编辑或生成一个通用的方法

第一个问题是更多的逻辑约束,但它也在ENC体系结构中遇到了一些限制。 即问题是产生第一类并不是非常困难。 麻烦的是在第二次编辑后生成这个类。 ENC引擎不仅需要跟踪符号表,而且还要跟踪生成的代码。 通常情况下,这并不是那么糟糕,但是当生成的类的形状基于使用它的上下文时,这变得越来越困难(因为使用闭包的lambda就是这种情况)。 更重要的是,你如何解决在这个过程中已经存在的类的实例的差异?

第二个问题是CLR ENC架构的严格限制。 C#(或VB)没有什么能够解决这个问题。

不幸的是,兰巴达斯遇到了这两个问题。 简短的说法是,对一个lambda进行ENC化,会在现有的类中引入大量的突变(这可能是也可能不是由其他ENC产生的)。 最大的问题在于解决新代码和当前进程空间中现有的闭包实例之间的差异。 另外,lambda比其他代码更倾向于使用generics,并且碰到问题#2。

细节是相当毛茸茸的,有点太正常的SO回答。 我已经考虑写一个关于这个问题的冗长的博客文章。 如果我解决它,我会把它链接回这个特定的答案。

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

在VB中部分支持这个特性,而不是在C#中有点遗憾: http : //msdn.microsoft.com/en-us/library/bb385795.aspx

在C#中实现相同的行为,对于包含lambdaexpression式的函数,我们不需要修改lambdaexpression式或任何依赖于它们的expression式,也可能不需要“怪物成本”,因此可以将痛苦程度降低80%。

如果是这样,重新开始一个unit testing应该花费几秒钟的时间。 我从来没有喜欢“编辑和继续”的模式说实话 – 你应该总是从头开始重新运行国际海事组织,以防万一中途执行的变化会影响早先运行的代码。 鉴于此,您最好使用可以非常快速地运行的unit testing。 如果你的unit testing花了难以忍受的时间开始,那么你应该看看这个问题。

编辑:至于为什么它不工作 – 你可能会发现,它适用于一些lambda,但不是其他人。 不捕获任何variables(包括this )的Lambdaexpression式被caching在一个私有的静态variables中,这样只有一个委托实例被创build。 更改代码意味着重新初始化可能有我怀疑有趣的副作用的variables。