C# 调试包含 lambda 表达式的函数
我有一个带有 lambda 表达式的函数,类似于:
int maxOccurrences = ( from field in data select field ).Max( f => f.Occurrences )
PS 我确信上述语句有一个更好/更简洁/更惯用的版本,很高兴知道它可能是什么,尽管它对问题并不重要!
如果我在调试时修改函数中的任何其他内容(例如 Console.Write
表达式),调试器会指出:
修改包含 lambda 表达式的“方法”将阻止调试会话在启用“编辑并继续”时继续。
我想知道为什么会出现这种情况?
我本以为为lambda 函数生成的IL 和Console.Write 语句将是分开的,并且调试器可以在必要时更改和修改。关于 lamda 功能,我是否缺少一些基本概念?
I have a function with a lambda expression something like:
int maxOccurrences = ( from field in data select field ).Max( f => f.Occurrences )
P.S. I'm sure that there's a nicer / neater / more idiomatic version of the above statement, it might be nice to know what that might be, although its not important to the question!
If I modify anything else within the function whilst debugging say a Console.Write
expression, the debugger states:
Modifying a 'method' which contains a lambda expression will prevent the debug session from continuing while Edit and Continue is enabled.
I was wondering why this might be the case?
I would have thought that the IL generated for the lamba function and the Console.Write
statement would be separate and that the Debugger could alter and modify when necessary. Is there some fundamental concept that I'm missing concerning the lamda functionality?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这并不是说在所有情况下都不可能实现(我不这么认为)。不过,这将是一个需要开发的怪物功能。
当您的方法中包含 LINQ 语法时,通常会涉及幕后的一些匿名方法:
...或者只是在幕前(如您的示例中所示) :
匿名方法又被编译成带有实例方法的类型,以支持您编写的代码。
在上面的示例中,考虑
f =>; f.Occurrences
lambda。它被编译成具有单个实例字段的类型,其类型是该 lambda 中本地f
的类型;该类型包含一个返回f.Occurrences
的方法。因此,当代码最终枚举 LINQ 查询的结果时,会为
data
中的每个field
构造这个编译器生成的类型的实例,并且类型的单一方法已生成以支持f =>;正在调用 f.Occurrences
lambda 表达式来计算Max
。编辑并继续的问题是,如果正在编辑的方法中的 lambda 表达式发生任何更改,则需要更改生成的类型,而这不是一个选项。人们可能会认为,在 lambda 表达式本身没有任何改变的情况下,这仍然可以完成;只要捕获相同的局部变量并且匿名方法不变,在调试时修改具有这些特征的方法应该是可行的,就像 VS 中的“正常”方法一样。
但正如您所看到的,类型生成通常用于支持匿名方法,因此 LINQ 查询特别增加了编辑并继续过程的复杂性,并且在许多情况下使得它变得不可能(因为它需要完全更改生成的类型)。
我认为,我们刚刚决定,在假设可以工作的有限场景中尝试支持这种行为是不值得花费开发成本的。
It isn't that it would be impossible to achieve in all cases (I don't think). It would be a monster feature to develop, though.
When you've got LINQ syntax in your method, generally that involves some anonymous method either behind-the-scenes:
...or just flat-out in front of the scenes (as in your example):
An anonymous method in turn gets compiled into a type with instance methods to support the code you've written.
In the example above, consider the
f => f.Occurrences
lambda. This gets compiled into a type with a single instance field whose type is that of the localf
in that lambda; this type contains a method that returnsf.Occurrences
.So when the code ultimately enumerates over the result of your LINQ query, what's happening is that an instance of this compiler-generated type is being constructed for every
field
indata
and that type's single method which has been generated to support thef => f.Occurrences
lambda expression is being called to calculateMax
.The issue with edit-and-continue is that if there's any change to the lambda expressions in the method being edited, this necessitates changing the types generated, which is not an option. One would think this could still be done in the case where nothing is altered about the lambda expressions themselves; as long as the same locals are captured and the anonymous methods are unchanged, it should be feasible to modify a method with these characteristics while debugging just as it is for "normal" methods in VS.
But as you can see, the type generation used to support anonymous methods in general and therefore LINQ queries specifically adds a great deal of complexity to the edit-and-continue process, and in many cases makes it impossible (since it requires changing generated types completely).
I think it was just decided that it wasn't worth the development cost to even bother trying to support this behavior in the limited scenarios where it could hypothetically work.
或者您可以简单地迁移到 Visual Studio 2015 :)
VS 2015 中的“编辑并继续”功能允许使用 lambda 表达式编辑方法。
您可以在这里阅读更多详细信息:
http://blogs.msdn.com/b/visualstudioalm/archive/2015/04/29/net-enc-support-for-lambdas -and-other-improvements-in-visual-studio-2015.aspx
Or you can simply move to Visual Studio 2015 :)
The "Edit and Continue" feature in VS 2015 allows editing methods with lambda expressions.
You can read about it in more detail here:
http://blogs.msdn.com/b/visualstudioalm/archive/2015/04/29/net-enc-support-for-lambdas-and-other-improvements-in-visual-studio-2015.aspx
有一种非常简单的方法来调试lambda 表达式。使用内联委托将其转换为匿名方法。简单的。 :)
There is a really simple way to debug a lamba expression. Convert it to an anonymous method using an inline delegate. Simple. :)