Understanding “Strange” Code with OzCode

How many times has your “mission in life” been to continue a project that another company, client or some other colleague programmer wrote? My guess is… a lot!

But, before you can start fixing the code or writing some new stuff, you probably need to understand exactly what is going on and this can frequently be very frustrating.

There are many aspects that can make your life very difficult, for instance: Messy code, old “writing code” methodologies, no Unit Tests, some very long methods, misleading or irrelevant comments and so on.

One key method for understanding this so-called legacy code is debugging, debugging and some more debugging. But debugging is not always the cure if you don’t have the right tool for the job, especially when we are talking about LINQ.

Debugging LINQ queries?

LINQ offers a great querying mechanism, especially in its Lambda form. It works great when writing complex chaining queries, with just a few lines of code (or maybe even one).
But let’s face it – when you need to understand somebody else’s code, or even code that you wrote a while back it’s an entirely different story.

Take this query for example:

var result = tenants.SelectMany(tenant => apartments, (t, a) => new {t, a})
	.Where(o => o.t.SpareCash >= o.a.Rent)
	.Where(o => o.t.City.Equals(o.a.City))
	.OrderBy(o => o.t.FirstName)
	.Select(o => new
	{
		o.t.FirstName, o.t.LastName, o.a.Id, o.a.Rent
	});

Well, it’s not that complicated, but even if you know LINQ it may take a while to fully understand what this query does, and just as important, whether it could be implemented better.

Generally, the purpose of this query is to take a list of tenants and a list of apartments and return all combinations of tenants and apartments where the apartment location is the same as the tenant location, and where the tenants can afford to pay the rent.

How to debug and improve someone else’s query

With the help of a new OzCode tool called the LINQ Analysis Window, we can break down this complex query pipeline while debugging and see exactly what is going on in each step.

First let’s open our special window:

linqanalysiswindow

As you can see, the debugger reached the line of the query, and before executing it we have the option to Open the LINQ Analysis ToolWindow by clicking on the λ icon on line 37 and start analyzing.

Our first operation is SelectMany which is like a cross join operation and will provide us all combinations of tenants and apartments.

linqselectmany

Then we have a Where condition that will provide us only the combinations where the tenants have enough money to pay the rent in the apartments.

linqwhere1
As we can see, our LINQ Analysis Window helps us visualize which elements will go through to the next step, and allows us to see whether the condition is doing what we meant for it to do.

Our second Where condition will provide us only the combinations where the tenant city is the same as the apartment city.

linqwhere2

As we can see only the elements with the same location will go through to next step.

Next, our OrderBy is sorting the elements by the tenants’ “FirstName”.

And finally, Select returns the required combinations of the elements with the tenants’ “FirstName” and “LastName” and the apartments’ “Id” and “Rent”.

linqselect

As you can see, this can be very helpful in situations where we encounter code with not so readable LINQ queries.

What about Performance?

Even in this simple example with debugging and the help of OzCode we can maybe improve this query for our needs.
For instance, if we switch the place of the Where conditions as shown below, we will receive exactly the same result but we may go over significantly less elements. When dealing with very large collections this is always a good thing.
Something like that will be very hard to see and analyze without the LINQ Analysis Window.

Replacing

 .Where(o => o.t.SpareCash >= o.a.Rent).Where(o => o.t.City.Equals(o.a.City)) 

With

 .Where(o => o.t.City.Equals(o.a.City)).Where(o => o.t.SpareCash >= o.a.Rent) 

Conclusion

We saw that with the right tools, there is no need to fear “Strange” code anymore.

Now we can understand in depth the not so readable LINQ queries, and while doing so also improve our LINQ writing techniques and maybe even our program’s performance.

If you want to check it out for yourself, you can try the latest OzCode Early Access Preview which already includes the LINQ Debugging feature, and start debugging your code the right way!