所以,每次我在一个方法中写了一个lambda表达式或匿名方法,我没有得到完全,我被迫重新编译并重新启动整个应用程序或单元测试框架的顺序要解决这个问题。这非常令人烦恼,我最终浪费的时间比我首先使用这些结构所节省的时间多。如果可以的话,我会尽量远离他们,尽管Linq和lambdas是我最喜欢的C#功能之一。
我想有一个很好的技术理由说明为什么会这样,也许有人知道?此外,有谁知道它是否会在VS2010中修复?
感谢。
答案 0 :(得分:16)
是的,有一个很好的理由说明为什么你不能这样做。原因很简单就是成本。在C#(或VB)中启用此功能的成本极高。
编辑lambda函数是使用当前ENC(Edit'n'Continue)体系结构很难解决的一类ENC问题的特定情况。也就是说,ENC执行以下任何一种方法的ENC非常困难: -
第一个问题更多的是逻辑约束,但它也会在ENC架构中遇到一些限制。即问题是产生第一类并不是非常困难。在第二次编辑后生成课程有什么麻烦。 ENC引擎必须开始跟踪符号表,不仅是实时代码,还包括生成的类。通常情况下这并不是那么糟糕,但是当生成的类的形状基于使用它的上下文时(例如由于闭包而使用lambda的情况),这变得越来越困难。更重要的是,如何解决与流程中已存在的类的实例的差异?
第二个问题是CLR ENC架构的严格限制。 C#(或VB)没有什么可以解决这个问题。
不幸的是,Lambdas遇到了这两个问题。简短版本是ENC的lambda涉及现有类的许多突变(可能是也可能不是从其他ENC产生的)。最大的问题在于解决新代码与当前进程空间中存在的现有闭包实例之间的差异。此外,lambda倾向于使用泛型比其他代码更多,并遇到问题#2。
细节非常多毛,而且对于正常的答案来说有点过于牵强。我考虑过撰写一篇关于这个主题的冗长的博客文章。如果我接触它,我会将它链接回这个特定的答案。
答案 1 :(得分:1)
根据Supported Code Changes列表,您无法向现有类型添加字段。匿名方法被编译成奇怪命名的类(有点<>_c__DisplayClass1
),这些类正是:类型。即使您对匿名方法的修改可能不包括更改包含的变量集(添加那些会改变现有类的字段),我想这就是不可能修改匿名方法的原因。
答案 2 :(得分:1)
有点遗憾,VB中部分支持此功能,但C#中不支持此功能: http://msdn.microsoft.com/en-us/library/bb385795.aspx
在C#中实现相同的行为会使包含lambda表达式的函数的痛苦程度降低80%,我们不需要修改lambda表达式,也不需要修改任何依赖于它们的表达式,并且可能不会出现“怪物成本” ”
答案 3 :(得分:0)
重新启动单元测试应该花费几秒钟,如果是这样的话。我从来都不喜欢“编辑和继续”模型 - 你应该总是从头开始重新运行IMO,以防万一执行中途的变化会影响早先运行的代码。鉴于此,您最好使用可以快速周转的单元测试。如果您的单个单元测试需要花费无法忍受的时间,那么您应该考虑解决这个问题。
编辑:至于为什么它不起作用 - 你可能会发现它适用于一些lambda而不适用于其他lambda。不捕获任何变量(包括this
)的Lambda表达式缓存在私有静态变量中,因此只创建了一个委托实例。更改代码意味着重新初始化那个可能会产生我怀疑的副作用的变量。