每当我在一个方法中编写Lambda表达式或匿名方法时,如果我没有写对,我就被迫重新编译和重新启动整个应用程序或单元测试框架来修复它。这非常令人恼火,我最终浪费了比使用这些构造节省的时间还要多的时间。这太糟糕了,以至于我尽可能远离它们,尽管Linq和Lambda是我最喜欢的C#特性之一。
我认为有一个很好的技术原因会导致这种情况,或许有人知道吗?此外,有人知道这个问题是否会在VS2010中得到解决吗?
谢谢。
每当我在一个方法中编写Lambda表达式或匿名方法时,如果我没有写对,我就被迫重新编译和重新启动整个应用程序或单元测试框架来修复它。这非常令人恼火,我最终浪费了比使用这些构造节省的时间还要多的时间。这太糟糕了,以至于我尽可能远离它们,尽管Linq和Lambda是我最喜欢的C#特性之一。
我认为有一个很好的技术原因会导致这种情况,或许有人知道吗?此外,有人知道这个问题是否会在VS2010中得到解决吗?
谢谢。
为什么你不能编辑lambda函数?原因很简单,成本太高了。在C#(或VB)中启用此功能的成本非常高。
编辑lambda函数是难以通过当前ENC(Edit'n'Continue)架构解决的一类ENC问题特例。主要困难在于,对于以下情况中的任何一个,都很难修改或编辑ENC:
第一个问题更多的是逻辑约束,但它也遇到了ENC架构中的一些限制。问题在于生成第一个类并不是非常困难。麻烦在于在第二次编辑之后生成类。ENC引擎必须开始跟踪符号表,不仅跟踪活动代码,还要跟踪生成的类。通常情况下这不是大问题,但当基于其所使用的上下文来定义生成类的形状时(如由于闭包的原因而出现在lambda中),这变得越来越困难。更重要的是,如何解决与已经存在于进程中的类实例的区别?
第二个问题是CLR ENC架构的严格限制。C#(或VB)无法绕过此限制。
不幸的是,lambda函数正好同时遇到这两个问题。简而言之,ENC lambda涉及对现有类进行大量的修改(这些类可能已从其他ENC生成)。问题在于如何解决新代码与当前进程空间中现有闭包实例之间的差异。此外,lambda倾向于比其他代码更多地使用泛型,并且遇到了问题#2。
细节非常复杂,不适合在SO答案中详细解释。我考虑写一篇长篇博客文章。如果我能完成它,我将链接回这个特定的答案。
有点遗憾的是,这个功能在VB中部分支持,但在C#中不支持: http://msdn.microsoft.com/en-us/library/bb385795.aspx
在C#中实现相同的行为将会减少80%的痛苦程度,特别是对于包含lambda表达式的函数,我们不需要修改lambda表达式或任何依赖它们的表达式,而且可能不需要付出“巨大代价”。
<>_c__DisplayClass1
),它们恰好就是类型。即使您对匿名方法的修改不包括更改封闭变量的集合(添加这些将更改现有类的字段),我想这就是无法修改匿名方法的原因。 this )的Lambda表达式被缓存到私有静态变量中,因此仅创建委托的一个实例。 更改代码意味着重新初始化该变量,这可能会产生有趣的副作用。
我只是想指出,Visual Studio 在这种情况下对“编辑”的考虑可能有点愚蠢(或者至少可以这么说)。当我在 git 中检查旧提交并尝试运行单元测试时,结果出现了 9 个错误(其中包括 ENC0014 和其他一些错误)。
因此,在没有修改任何文件的情况下,每次我尝试调试单元测试时都会出现这些错误。重新启动 Visual Studio 可以消除这些错误,因此我猜测根本问题在于缺少缓存失效,即 Visual Studio 无法检测/响应通过其编辑器窗口之外的文件更改。