对于这个看似简单的问题,可以写很多东西!事实上,我已经在 Simple-Talk.com 上的文章LINQ Secrets Revealed: Chaining and Debugging中详细写过。以下是其关键点的摘要:
- 您可以使用调试器单步执行一些 LINQ 查询,但这取决于查询中表达式和语句的组成(因为您只能单步执行statements)。
- LINQ 方法链之所以起作用,是因为有一个基本规则:每个非终端方法都将
IEnumerable<T>
其作为输入并IEnumerable<T>
作为输出返回。
- 你可以注入一个“no-op”语句来给你一个“垫脚石”,如果你愿意的话,只要它符合那个基本规则。也就是说,意识到您总是可以
.Select(z => z)
毫无后果地放入方法链中,请使用它的变体,即:z => { return z; }
。
- 您可以类似地注入诊断方法来提供输出,而不仅仅是提供潜在的断点。LINQPad是出色的暂存器,不仅适用于 LINQ,而且通常适用于 C#,它以其强大的
Dump()
方法提供了这一点。Dump 是一个对象可视化工具,可提供复杂数据结构的惊人可视化。
- 基于 Bart De Smet 在其内容丰富的文章LINQ to Objects - 调试您可以将简化的风格
Dump
带回 Visual Studio 中的工作 - 我提供了附加到我在顶部提到的文章的代码。
- 感谢 Robert Ivanc 在LINQPad Visualizer上的工作,您甚至可以将 LINQPad 可视化器带入 Visual Studio(尽管您需要为单个表达式手动启动它;您不能将其连接到
Dump()
方法)。
作为一个简单的例子,考虑这个简单的方法链:
string[] Words = new string[]
{" KOOKABURRA", "Frogmouth", "kingfisher ", "loon", "merganser"};
Words
.Select(word => word.Trim())
.Select(word => word.ToLower())
.Where(word => word.StartsWith("k"))
.OrderBy(word => word);
在 Visual Studio 项目中包含 Dump 扩展方法后,您可以像这样最低限度地检测它...
Words
.Select(word => word.Trim())
.Dump()
.Select(word => word.ToLower())
.Dump()
.Where(word => word.StartsWith("k"))
.Dump()
.OrderBy(word => word)
.Dump();
...或者更详细地像这样...
Words
.Dump(w => "ORIGINAL: " + w, ConsoleColor.Yellow)
.Select(word => word.Trim())
.Dump(w => "TRIMMED: " + w, ConsoleColor.Yellow)
.Select(word => word.ToLower())
.Dump(w => "LOWERCASE: " + w, ConsoleColor.Green)
.Where(word => word.StartsWith("k"))
.Dump(w => "FILTERED to 'K': " + w, ConsoleColor.Red)
.OrderBy(word => word)
.Dump(w => "SORTED: " + w, ConsoleColor.Blue);
... 将输出分别呈现为图形的左侧或右侧:
作为一个预告片,我会说虽然这确实很有用,但您确实必须看到 LINQPad 可以使用相同的输出实现的增强可视化(为了您的方便,这里再次提供链接)。