{"id":69206,"date":"2016-12-01T14:01:21","date_gmt":"2016-12-01T14:01:21","guid":{"rendered":"https:\/\/www.simple-talk.com\/?p=69206"},"modified":"2021-06-03T16:47:06","modified_gmt":"2021-06-03T16:47:06","slug":"linq-debugging-visualization","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/linq-debugging-visualization\/","title":{"rendered":"LINQ Debugging and Visualization"},"content":{"rendered":"<p>Microsoft\u2019s Language-Integrated Query (LINQ) technology is fast approaching its tenth anniversary. The earliest reference I\u2019ve found is from <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/bb308959.aspx\">February, 2007<\/a>, which was a lengthy article by Don Box and Anders Hejlsberg. Since then, you might think that everything that needs to be said about LINQ has been said. It hasn\u2019t, in fact, all been said, because I need to point out in this article LINQ has at last got the Debugger it always deserved and needed, thanks to a new feature coming in the next release of OzCode. <a href=\"https:\/\/oz-code.com\/\">OzCode<\/a> is a Visual Studio extension that improves the debugging experience immensely: It is relatively new so it is not that well known, but it has been around long enough, more than two and a half years, to prove its mettle with many developers.<\/p>\n<p>Since the 2.0 release of OzCode, the development team at OzCode has focused on the flagship feature of the next release, LINQ debugging. As an early adopter of OzCode, I jumped at the chance to participate in their early access program for this upcoming release. I rarely write about products per se\u2014I think I have done it twice in my last hundred or so articles\u2014as I do not want to appear like a huckster for the company. But this LINQ debugging capability is so useful it really deserves the attention here. Just to be clear, I have no association with OzCode other than being an avid user. (Ed: OzCode is nothing to do with us either)<\/p>\n<p>I am going to jump right in and show you how LINQ visualization works with OzCode in Visual Studio. I\u2019ll skip my usual type of preamble that, in this case, would include discussing command pipelining, method chaining, LINQ logistics, and debugging limitations &amp; options before OzCode. The reason is that my prior article, <a href=\"https:\/\/www.simple-talk.com\/dotnet\/net-framework\/linq-secrets-revealed-chaining-and-debugging\/\">LINQ Secrets Revealed: Chaining and Debugging<\/a>, already covers those in depth and I urge you to review that article before continuing. Though that article is six years old (to the day!), the vast majority of it is still relevant today. And it is a great stepping stone for today\u2019s topic. In fact, to show the improvements provided by OzCode I am going to continue the same set of examples.<\/p>\n<h2>Visualizations Before OzCode<\/h2>\n<p>The first code sample is the simple LINQ chain in <strong>ProcessWordList1<\/strong>. (This code is available in the <strong>LinqMethodChaining<\/strong> project of the <strong>LinqDebuggingWithOzCode<\/strong> solution attached to this article.)<\/p>\n<pre>class Program\r\n{\r\n    static readonly string[] Words =\r\n        {\"   KOOKABURRA\", \"Frogmouth\", \"kingfisher   \", \"loon\", \"merganser\"};\r\n \r\n    static void Main()\r\n    {\r\n        var newWords = ProcessWordList1(Words);\r\n        foreach (var word in newWords)\r\n        {\r\n            Console.WriteLine(word);\r\n        }\r\n        Console.ReadLine();\r\n    }\r\n \r\n    private static IEnumerable ProcessWordList1(string[] words)          \r\n    {\r\n      return words\r\n        .Select(word =&gt; word.Trim())\r\n        .Select(word =&gt; word.ToLower())\r\n        .Where(word =&gt; word.StartsWith(\"k\"))\r\n        .OrderBy(word =&gt; word);\r\n    }\r\n}\r\n<\/pre>\n<p>In the prior article, I showed how to instrument that code to inject watchers that would allow a very crude visualization on the console. In Figure 1, you can see movement of each input element through the LINQ chain. The output on the left comes from injecting the custom <strong>EnumerableDebugger<\/strong> with default settings, whereas the output on the right shows the same thing with some customization arguments passed in.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"641\" height=\"331\" class=\"wp-image-69207\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-13.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 1<\/p>\n<p>The figure\u2014particularly the right side\u2014certainly provides useful information, but it requires extensively instrumenting your code to get that output, and even then it is console output rather than something that is available in the debugger.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"246\" height=\"457\" class=\"wp-image-69208\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-62.png\" \/><\/p>\n<p class=\"caption\">Figure 2<\/p>\n<p>The next step I introduced was to take the code over to Joseph Albahari\u2019s <a href=\"http:\/\/www.linqpad.net\/\">LINQPad<\/a>, a very handy sandbox for sketching out your code, because its forte is LINQ visualization. In Figure 2, you have a clearer picture of the data moving through the LINQ method chain, but this also has a number of drawbacks. First, it is divorced from Visual Studio completely so quite disruptive in terms of workflow: You need to copy code from Visual Studio into LINQPad. You also have to manually instrument the code with LINQPad\u2019s Dump method to output the visualizations. Here\u2019s what it looks like:<\/p>\n<pre>string[] Words = new string[]\r\n{\r\n\t\"   KOOKABURRA\",\r\n\t\"Frogmouth\",\r\n\t\"kingfisher   \",\r\n\t\"loon\",\r\n\t\"merganser\"\r\n};\r\nWords\r\n   .Dump(\"ORIGINAL:\")\r\n   .Select(word =&gt; word.Trim())\r\n   .Dump(\"TRIMMED:\")\r\n   .Select(word =&gt; word.ToLower())\r\n   .Dump(\"LOWERCASE:\")\r\n   .Where(word =&gt; word.StartsWith(\"k\"))\r\n   .Dump(\"FILTERED to 'K':\")\r\n   .OrderBy(word =&gt; word)\r\n   .Dump(\"SORTED:\");\r\n<\/pre>\n<p>The final approach I offered in my previous article was that of using Robert Ivanc\u2019s <a href=\"http:\/\/code.google.com\/p\/linqpadvisualizer\/\">LINQPad Visualizer<\/a>, a plug-in of sorts for Visual Studio that lets you generate the same LINQPad visualizations within Visual Studio using the Watch window. That technique allowed you to stay in Visual Studio, and also removed the impediment of having to decorate the code (i.e. it did not require adding the Dump method calls), but I assume it never really garnered enough interest as the web page shows support only through Visual Studio 2012.<\/p>\n<p>All of these debugging techniques are ways to dance around the true issue; needing to visualize a LINQ chain in situ. That is, ideally it should require no code instrumentation, should allow interacting with a LINQ chain with the same ease that Visual Studio allows you when interacting with variables and objects while stopped at a breakpoint. Let\u2019s explore how OzCode delivers this experience.<\/p>\n<h2>OzCode: A First Look at LINQ Exploration<\/h2>\n<p>In Figure 3, I am in the debugger in Visual Studio 2015 and have just stepped onto the return statement of <strong>ProcessWordList1<\/strong>. Visual Studio has highlighted the entire LINQ chain in yellow.<\/p>\n<p>The first thing to notice, unrelated to LINQ, is the decoration of the method signature, that <strong>string[5]<\/strong> above the parameter sitting in a shallow tray. That is OzCode\u2019s standard <a href=\"https:\/\/en.wikipedia.org\/wiki\/Head-up_display\">Heads Up display<\/a>. Like its namesake from the automotive industry, it is a feature that presents data right in front of you, so you do not have to look in your Locals window, Watch window, etc. Here it is just letting us know the passed in array has five elements. More on that shortly.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"151\" class=\"wp-image-69209\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-63.png\" \/><\/p>\n<p class=\"caption\">Figure 3<\/p>\n<p>The second thing to notice is that each expression in the LINQ chain is decorated with a numerical marker, e.g. <img loading=\"lazy\" decoding=\"async\" width=\"19\" height=\"12\" class=\"wp-image-69210\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-64.png\" \/> . Those numbers indicate how many elements are in the sequence at that point in the chain. In other words, the source (words) starts with five elements then goes through a couple Select expressions. Since Select does not change the cardinality of a sequence, it shows five on both of those as well. Then, the Where expression filters the list down to two, and <strong>OrderBy<\/strong> maintains that list size, also showing two elements.<\/p>\n<p>Note that, if the size or complexity of your sequences are great enough, OzCode will <em>not<\/em> automatically execute the sequence in case that impedes Visual Studio\u2019s responsiveness. When OzCode detects that this might happen, you will see a question mark <img loading=\"lazy\" decoding=\"async\" width=\"19\" height=\"13\" class=\"wp-image-69211\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-65.png\" \/> rather than a number in each marker; clicking on any one will evaluate the sequence and fill in the numbers.<\/p>\n<p>Next I click on the first marker, shown by the arrow I have added on the left side of Figure 4.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-69308\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/12\/figure4.png\" alt=\"figure4\" width=\"640\" height=\"211\" \/><\/p>\n<p class=\"caption\">Figure 4<\/p>\n<p>The action of clicking on that marker \u2026<\/p>\n<ol>\n<li>Inverts the colors and darkens the selected marker to show it is the current sequence in the chain.<\/li>\n<li>Changes the contents of the marker to show both the position of the current element in the current sequence and the length of that sequence.<\/li>\n<li>Opens a <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ea46xwzd.aspx\">DataTip<\/a>-like window enumerating the current sequence.<\/li>\n<li>Activates the current sequence so you can navigate around it with the mouse or the arrow keys.<\/li>\n<\/ol>\n<p>Note carefully the distinction between current <em>sequence<\/em> and current <em>element<\/em> in the above.<\/p>\n<p>In Figure 4, the <strong>current sequence<\/strong> is the list of data elements as it exists at some point in the LINQ chain. I clicked on the very first marker, so the current sequence at that point is just the input (or <em>source <\/em>as OzCode prefers to call it), which is the contents of the variable words. That\u2019s just what you see in the DataTip on the right of the figure.<\/p>\n<p>A current sequence always has to have a <strong>current element<\/strong>, i.e. one member of the sequence that is highlighted and notated in some fashion. When you click on a sequence and activate it, the first element in that sequence automatically becomes the current element. Thus, the <img loading=\"lazy\" decoding=\"async\" width=\"30\" height=\"13\" class=\"wp-image-69213\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-66.png\" \/> expression you see in the marker that I just clicked on means the first element in the sequence is the current element and there are five elements in the current sequence. Over on the right of the Figure 4, the second arrow I have added is pointing to the current element\u2014the first element at the moment\u2014that, from a list perspective, is at index zero.<\/p>\n<h2>Walking through Elements<\/h2>\n<p>To recap Figure 4, the current sequence is just the input, words. The current element is the first element, \u201c KOOKABURRA\u201d (with some extra leading spaces). So now let\u2019s advance to the next element in the current sequence. There are three ways to do that:<\/p>\n<ul>\n<li>Press the down arrow key to advance to the next element.<\/li>\n<li>Hover over the marker and use your mouse wheel to scroll down the list.<\/li>\n<li>Click on the second element in the DataTip.<\/li>\n<\/ul>\n<p>Whichever technique you use to do this, the marker values and the DataTip highlight remain in sync, advancing in lockstep together. The arrows in Figure 5 shows that I have now bumped the current element to the second value in the input but have not changed the current sequence<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-69309\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/12\/figure5.png\" alt=\"figure5\" width=\"640\" height=\"185\" \/><\/p>\n<p class=\"caption\">Figure 5<\/p>\n<p>Note that if your sequence is long enough, the DataTip will show a vertical scrollbar. You can then hover over the DataTip and use your mouse wheel to scroll up and down in the list, but it will <em>not<\/em> affect the current element, only the portion of the sequence that you are viewing.<\/p>\n<p>Now I want to draw your attention back to the source code, jumping back to Figure 4 (that\u2019s 4, not 5). Notice the Heads Up display in Figure 4 shows the transformations of the first element as it progresses through each sequence! So in the figure, you see just above the first Select expression (which does a <strong>Trim<\/strong>) the leading spaces on \u201c KOOKABURRA\u201d have been stripped off. In the second Select, which does a\u00a0<strong>ToLower<\/strong>, it shows that the value has indeed been converted to lower case, and it remains that way through to the OrderBy expression. Similarly, in Figure 5 now, you see the transformations of the second element in the sequence. But here a curious thing happens: the second element does <em>not<\/em> pass the filter embodied by the Where expression: since it no longer exists in the list after the Where is executed, there is no position in the list to report, hence the <img loading=\"lazy\" decoding=\"async\" width=\"28\" height=\"13\" class=\"wp-image-69215\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-68.png\" \/> marker. That represents the fact that there was input but no output. Whereas in the final sequence, the\u00a0<strong>OrderBy<\/strong>, there is not even any input\u2014with respect to the <em>current<\/em> element\u2014so that is represented as a null in the marker ( <img loading=\"lazy\" decoding=\"async\" width=\"33\" height=\"13\" class=\"wp-image-69216\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-69.png\" \/> ).<\/p>\n<p>Also note that the green shading represents a true result (Figure 4) and red shading represents a false result (Figure 5) on the Boolean expressions. Those expressions are trivial here but OzCode will individually color-code each Boolean sub-expression in a complex expression so you can see at a glance what is happening. Figure 6 is taken from OzCode\u2019s web site. Here you can instantly see what was true and what was false. (And the <em>Simplify<\/em> tool even allows you to walk through the Boolean expression tree to analyze its components further, should you need to.)<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"539\" height=\"152\" class=\"wp-image-69217\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-70.png\" \/><\/p>\n<p class=\"caption\">Figure 6<\/p>\n<h2>Walking Through Sequences<\/h2>\n<p>The previous section described how to move between elements in the current sequence. To move among the different sequences, there are again several options.<\/p>\n<p>First, you can click the marker adjacent to a given sequence in the code. That will move the element highlighting to that marker and update the DataTip context to display the selected sequence. (Actually, you do not even have to click; just hovering over a marker is sufficient!)<\/p>\n<p>Second, inside the DataTip you can effectively see two sequences\u2014the input and output of any given LINQ method in the chain. For example, in Figure 7 I have hovered over the\u00a0<strong>Select<\/strong> expression that calls <strong>Trim <\/strong>and the DataTip shows the <em>output<\/em> of that\u00a0<strong>Select<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"226\" class=\"wp-image-69218\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-71.png\" \/><\/p>\n<p class=\"caption\">Figure 7<\/p>\n<p>But inside the DataTip you can switch to showing the <em>inputs<\/em>, effectively showing the sequence prior to the current sequence. In Figure 8 I have clicked on the input icon of the\u00a0<strong>Select<\/strong> in the DataTip\u2014just where the red arrow is pointing. So the highlighting of the top bar in the DataTip has moved from the output (Figure 7) to the input (Figure 8), and the body of the DataTip in Figure 8 correspondingly shows the input list (notice the extra leading spaces on element 0 and extra trailing spaces on element 2).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"233\" class=\"wp-image-69219\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-72.png\" \/><\/p>\n<p class=\"caption\">Figure 8<\/p>\n<p>The final approach to moving among sequences is with the <em>LINQ analysis window<\/em>. Open the LINQ analysis window by pressing either lambda button highlighted with the green arrows in Figure 8; the result appears in Figure 9.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"228\" class=\"wp-image-69220\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-73.png\" \/><\/p>\n<p class=\"caption\">Figure 9<\/p>\n<p>The added benefit you get from this LINQ analysis window is that you can see each LINQ sequence along with the input and transformations that created that sequence. That is, you see both the input and output sequences (or the \u201cbefore\u201d and \u201cafter\u201d if you prefer), and you see precisely how the input elements map to the output elements with connecting lines. Those connecting lines are faint grey except for the current element, which is highlighted in purple\u2014the same current element still shown in the code in the main editor window! Yes, even though this is now a first-class window rather than just a DataTip, it is still intimately tied to your code. If you select a different current element in the code, it reflects in the window, and vice versa.<\/p>\n<p>Similarly, notice that the current sequence is highlighted in the LINQ analysis window in the top bar of LINQ keywords\u2014the first\u00a0<strong>Select <\/strong>in this case. That same <strong>Select <\/strong>expression is also highlighted in the code editor. If you select a different LINQ keyword in the window it is reflected back in the code, and vice versa. To navigate amongst the different LINQ sequences in the analysis window, just click on one of those keywords in the top row.<\/p>\n<p>The mapping in Figure 9, though, is rather uninteresting: a <strong>Select<\/strong> is just a one-to-one mapping. In Figure 10, though, where I have clicked on the Where expression, the mapping provides much more useful information. Here you can see for the entire sequence which elements passed the filter and which did not, along with how their positions shifted in the sequence.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"228\" class=\"wp-image-69221\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-74.png\" \/><\/p>\n<p class=\"caption\">Figure 10<\/p>\n<h2>More on the LINQ Analysis Window<\/h2>\n<p>In this next example, taken from the samples provided when you install OzCode, the code uses a\u00a0<strong>SelectMany<\/strong>, a LINQ operator that is less familiar and thus a bit less intuitive to understand at first glance. Figure 11 shows the code.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"507\" height=\"213\" class=\"wp-image-69222\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-75.png\" \/><\/p>\n<p class=\"caption\">Figure 11<\/p>\n<p>The first thing to notice is the Heads Up display on the code. From that you can see that there are 3 departments, and the average for the first department is 44.8. If you walk through the sequence, you\u2019ll see the averages for each of the departments there. We\u2019ll come back to the code in a bit to see what more we can glean in a moment. But first, take a look at the LINQ analysis window for this code in Figure 12. Here I have opened up the\u00a0<strong>SelectMany<\/strong> sequence.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"636\" height=\"315\" class=\"wp-image-69223\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-76.png\" \/><\/p>\n<p class=\"caption\">Figure 12<\/p>\n<p>This helps you visualize what a <strong>SelectMany<\/strong> actually does. The second element (index 1) on the input side expands into 6 elements (indices 2 through 7) on the output side. But the<strong>Student <\/strong>instances listed in the output are not providing any useful information. Because the\u00a0<strong>Student <\/strong>class does not have an override for the <strong>ToString<\/strong> method you just see the class name repeatedly. Here we leverage another base OzCode feature (i.e. independent of the LINQ capabilities) called <em>Reveal<\/em>. In Figure 13 I have expanded the fourth item in the output (nothing special about the fourth one; any one will do). I have also clicked on the star next to the\u00a0<strong>Grade<\/strong> and <strong>Name<\/strong> properties so those have changed from grey to gold.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"282\" class=\"wp-image-69224\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-77.png\" \/><\/p>\n<p class=\"caption\">Figure 13<\/p>\n<p>As soon as I did that, notice what happened not just to that fourth element but to every element on the output side in Figure 13: the properties I selected have effectively generated a\u00a0<strong>ToString<\/strong> method for the<strong> Student<\/strong> class on-the-fly! And that information is not transient; you can close the LINQ analysis window, close the project, even close Visual Studio\u2026 the next time you open up a Student, whether in the LINQ analysis window or in a standard Visual Studio DataTip, those same properties will still be used instead for its\u00a0<strong>ToString<\/strong> representation.<\/p>\n<p>The way that <em>Reveal<\/em> works illustrates how well OzCode has integrated all of its capabilities into a cohesive whole. Just like I selected properties to override the\u00a0<strong>ToString<\/strong> method for <strong>Student<\/strong>, I went back to the\u00a0<strong>Select <\/strong>sequence in the LINQ analysis window, and selected the\u00a0<strong>Name<\/strong> property to override the <strong>ToString<\/strong> method for<strong>Department<\/strong> instances. Figure 14 shows how that reflects in the Heads Up display back in the code editor. Compare that to how you just saw class names in Figure 11.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"528\" height=\"184\" class=\"wp-image-69225\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-78.png\" \/><\/p>\n<p class=\"caption\">Figure 14<\/p>\n<h2>Exception Handling<\/h2>\n<p>OzCode also provides excellent support in the case of exceptions. In Figure 15 I have modified OzCode\u2019s demo code to force an exception (notice that I nulled out the Name property of one item at the top of the code). In the figure, I have just stepped onto the entire LINQ chain in the debugger. Before it is even executed, OzCode warns you about an impending\u00a0<strong>NullReferenceException<\/strong> at the top. It also tells you which sequence has the issue: notice the second marker\u2014on the\u00a0<strong>Select <\/strong>sequence\u2014is in red ( <img loading=\"lazy\" decoding=\"async\" width=\"19\" height=\"9\" class=\"wp-image-69226\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-79.png\" \/> ).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"535\" height=\"243\" class=\"wp-image-69227\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-80.png\" \/><\/p>\n<p class=\"caption\">Figure 15<\/p>\n<p>To dig further, open up the LINQ analysis window and it confirms the problem on that\u00a0<strong>Select <\/strong>sequence with the warning icon that I have circled near the top of Figure 16. Examining the output side of the sequence contents, you see the typical text associated with a null reference (\u201cObject reference not set\u2026\u201d) , so tracing back to the input, I have expanded that element in the sequence and found a null value, which I\u2019ve also circled in the figure.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"258\" class=\"wp-image-69228\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-81.png\" \/><\/p>\n<p class=\"caption\">Figure 16<\/p>\n<h2>A Rock and a Hard Place<\/h2>\n<p>OzCode\u2019s new LINQ debugging capability is tremendous, no doubt about it. But it is not a panacea; it is still constrained by Visual Studio\u2019s own modeling capability. As a case in point, Figure 17 shows another example from my earlier article. This code comes from an open-source application I wrote called <em>HostSwitcher<\/em>. In a nutshell, HostSwitcher lets you re-route entries in your hosts file with a single click on the context menu attached to the icon in the system tray. I discussed the LINQ debugging aspects of this code in the same article I mentioned previously, <a href=\"https:\/\/www.simple-talk.com\/dotnet\/net-framework\/linq-secrets-revealed-chaining-and-debugging\/\">LINQ Secrets Revealed: Chaining and Debugging<\/a>, but if you want a full understanding of the entire HostSwitcher application, see my other article that discusses it at length, <a href=\"http:\/\/www.simple-talk.com\/dotnet\/.net-framework\/creating-tray-applications-in-.net-a-practical-guide\/\">Creating Tray Applications in .NET: A Practical Guide<\/a>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"472\" class=\"wp-image-69229\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-82.png\" \/><\/p>\n<p class=\"caption\">Figure 17<\/p>\n<p>The result of the code in Figure 17 is a dictionary. The key is a project name and the value is a list of\u00a0<strong>ServerGroup<\/strong> objects. A<strong> ServerGroup<\/strong> object contains the name of a server and the number of IP addresses that are enabled or disabled on that server at any given instant. I am sure this verbal description is not completely satisfying; you likely have a general idea what I mean, but I doubt if you have a very good mental image of it. Looking at the Heads Up data in Figure 17, you can see a project name, but you do not get much regarding the list of <strong>ServerGroups<\/strong>. So let\u2019s open up the DataTip for the <strong>ToDictionary<\/strong> sequence (Figure 18). Because I have already expanded items in the DataTip and circled the crucial values you can quickly get a much better idea of what is going on.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"372\" class=\"wp-image-69230\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-83.png\" \/><\/p>\n<p class=\"caption\">Figure 18<\/p>\n<p>There is useful information here but mixed in with superfluous information that we really do not care about. Is there a more concise, visually rich way to see the data? Yes, but alas, not from OzCode. Figure 19 shows a very concise visualization of all and only the data we care about, generated by LINQPad.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"483\" height=\"304\" class=\"wp-image-69231\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/11\/word-image-84.png\" \/><\/p>\n<p class=\"caption\">Figure 19<\/p>\n<p>But remember the trade-offs mentioned early in the article: LINQPad is separate from Visual Studio and you have to instrument the code with Dump calls. The latter is simple, as is copying your code into LINQPad, but feeding it your data may not be a trivial task!<\/p>\n<h2>Conclusion<\/h2>\n<p>Ten years on from the introduction of the magic of LINQ to .NET software development, OzCode delivers a debugging experience that LINQ always deserved. From the Heads Up display you can see how a single element transforms through an entire LINQ chain; and from DataTips you can see all the values in one sequence at one time. Additionally, with the LINQ analysis window, you can see all the values of two sequences at one time. Arguably, the only missing feature in OzCode is showing <em>all<\/em> the values through <em>all<\/em> the sequences in one window, but that is more a limitation of screen real estate. Nonetheless, this new LINQ debugging capability should provide a great productivity boost to any software development effort.<\/p>\n<p>Final notes: First, be aware that I wrote this article using a pre-release edition of OzCode, so features are of course subject to change in the final version. Also, I did find a few minor bugs in the course of my evaluation that I\u2019ve since reported to the development team\u2014minor enough that they do not even warrant going into any details here\u2014and I have high hopes that those will also be fixed in the final version.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>LINQ is certainly extraordinarily useful. It brings the power of query expressions to C#, allowing an easy way of getting the data you need from a variety of data sources. Up to now, there hasn&#8217;t been a VS debugger for LINQ that gives you the means to visualise the data at every point in the chain.  Michael Sorens, a keen LINQ user,  describes a third-party tool that now promises to make using LINQ  something we can all participate in.&hellip;<\/p>\n","protected":false},"author":221868,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[],"coauthors":[6802],"class_list":["post-69206","post","type-post","status-publish","format-standard","hentry","category-dotnet-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/69206","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221868"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=69206"}],"version-history":[{"count":17,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/69206\/revisions"}],"predecessor-version":[{"id":90908,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/69206\/revisions\/90908"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=69206"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=69206"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=69206"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=69206"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}