C#调试包含lambda表达式的函数

TK.*_*TK. 16 c# debugging lambda

我有一个lambda表达式的函数,如:

int maxOccurrences = ( from field in data select field ).Max( f => f.Occurrences )
Run Code Online (Sandbox Code Playgroud)

PS我确信上面的声明有一个更好/更整洁/更惯用的版本,知道它可能是什么可能会很好,虽然它对问题不重要!

如果在调试Console.Write表达式时调用函数中的任何其他内容,则调试器会声明:

修改包含lambda表达式的"方法"将阻止在启用"编辑和继续"时继续调试会话.

我想知道为什么会这样呢?

我原本认为为lamba函数和Console.Write语句生成的IL 将是独立的,并且调试器可以在必要时进行更改和修改.是否有一些关于lamda功能的基本概念?

Dan*_*Tao 11

并非在所有情况下都无法实现(我不认为).不过,这将是一个怪物特征.

当你的方法中有LINQ语法时,通常会在幕后使用一些匿名方法:

// This LINQ query...
var fields = from field in data select field;

// ...is equivalent to this:
var fields = data.Select(f => f);
Run Code Online (Sandbox Code Playgroud)

...或者只是在场景平放(如在你的例子中):

( from field in data select field ).Max( f => f.Occurrences ) // <- lambda
Run Code Online (Sandbox Code Playgroud)

反过来,匿名方法被编译成一个带有实例方法的类型,以支持您编写的代码.

在上面的例子中,考虑f => f.Occurrenceslambda.这被编译成一个具有单个实例字段的类型,其类型是f该lambda 中的本地字段的类型; 此类型包含返回的方法f.Occurrences.

因此,当代码最终枚举LINQ查询的结果时,正在发生的是正在为每个fieldin 构造此编译器生成类型的实例,data并且该类型的单个方法被生成以支持f => f.Occurrenceslambda表达式被调用计算Max.

编辑并继续的问题是,如果正在编辑的方法中的lambda表达式有任何更改,则必须更改生成的类型,这不是一个选项.有人会认为在lambda表达式本身没有任何改变的情况下仍然可以做到这一点; 只要捕获了相同的本地并且匿名方法没有改变,在调试时修改具有这些特性的方法应该是可行的,就像在VS中使用"普通"方法一样.

但正如您所看到的,一般用于支持匿名方法的类型生成因此LINQ查询特别为编辑和继续过程增加了大量复杂性,并且在许多情况下使其无法实现(因为它需要更改生成的类型)完全).

我认为只是决定开发成本不值得尝试在有限的情况下支持这种行为,它可以假设工作.