I can’t begin to explain how excited I get when working with Linq. Until now, there were times that you needed to write a large amount of code to do the same basic operations like determining a child object had certain properties set, or determine the count of how many times a property is set to true.
You would have to declare a bunch of variables like “bool found;” and then you would perform a foreach loop on your objects, checking for certain conditions. Since you did the same thing over and over, you would go and find a code block that was close and modify it to fit your needs. Now there is a much more precise, easy to read syntax to perform the basic crud tasks, and they call it Linq.
With the power of Linq, you no longer have to write long winded code to walk all the items in a collection only to realize two or three of the twenty items are valid. You can now filter or select the objects that you would like to work with, with straight forward query syntax.
NCover stores the coverage file in an xml document. In that document is all the information needed to determine what classes are in a namespace, what methods are contained in a class and so forth. You can think of these as relationships or “joins”. Once this information is loaded into memory, you could perform a foreach loop against every single class in every single namespace until you found a match or you could query the data for exactly what you are looking for.
A typical query against an NCover coverage file could look like this:
CodeCoverage c = CodeCoverage.Load(file);
var retVal =from mod in c.Modules
from cls in mod.Classes
from method in cls.Methods
where method.Name == ".ctor"
select method;
In the above example each collection is aliased with a name, which can be used in the where clause with full Intellisense. You could easily add an additional where statements to only find .ctors (constructors) in a class that start with “GCheckout”. This syntax would look like this:
CodeCoverage c = CodeCoverage.Load(file);
var retVal =from mod in c.Modules
from cls in mod.Classes
from method in cls.Methods
//only list classes in the GCheckout Namespace
where cls.NameSpace == "GCheckout"
where cls.Name.StartsWith("Request")
where method.Name == ".ctor"
select method;
You may notice that there are multiple instances where clauses in the Linq query. You could have just as easily replaced the second where keyword with && (in c#). I personally feel it is easier to read the intention of the statement by spelling out where on every “filter”.
My thought was the majority of people were going to want to perform queries against the classes and methods. I rolled up all the classes and methods on the CodeCoverage class in order to remove the need to reference the relationships between the modules and the classes and the methods.
CodeCoverage c = CodeCoverage.Load(file);
var retVal =from method in c.Methods
from param in method.Parameters
where param.FullType == typeof(decimal).ToString()
orderby method.Name
select method;
Download the sample code and tell me what you think.
LinqToNCover.zip (94.82 kb)
The next article will talk about how a Linq query was used to calculate the return value of a property.