C# LINQ Keywords - The from Clause and Range Variables

Each query begins with a from clause. The from clause is a generator that also defines the range variable, which is a local variable of sorts used to represent each item of the input collection as the query expression is applied to it. The from clause is just like a foreach construct in the imperative programming style, and the range variable is identical in purpose to the iteration variable in the foreach statement. A query expression might contain more than one from clause. In that case, you have more than one range variable, and it’s analogous to having nested foreach clauses. The next example uses multiple from clauses to generate the multiplication table you might remember from grade school, albeit not in tabular format:
<pre class="brush:csharp">
using System;
using System.Linq;

public class MultTable
{
static void Main() {
var query = from x in Enumerable.Range(0,10)
from y in Enumerable.Range(0,10)
select new {
X = x,
Y = y,
Product = x * y
};
foreach( var item in query ) {
Console.WriteLine( "{0} * {1} = {2}",
item.X,
item.Y,
item.Product );
}
}
}
</pre>
Remember that LINQ expressions are compiled into strongly typed code. So in this example, what is the type of x and what is the type of y? The compiler infers the types of those two range variables based upon the type argument of the IEnumerable<T> interface returned by Range. Because Range returns a type of IEnumerable<int>, the type of x and y is int. Now, you might be wondering what happens if you want to apply a query expression to a collection that only supports the nongeneric IEnumerable interface. In those cases, you must explicitly specify the type of the range variable, as shown here:
<pre class="brush:csharp">
using System;
using System.Linq;
using System.Collections;

public class NonGenericLinq
{
static void Main() {
ArrayList numbers = new ArrayList();
numbers.Add( 1 );
numbers.Add( 2 );
var query = from int n in numbers
select n * 2;
foreach( var item in query ) {
Console.WriteLine( item );
}
}
}
</pre>
You can see where I am explicitly typing the range variable n to type int. At run time, a cast is performed, which could fail with an InvalidCastException. Therefore, it’s best to strive to use the generic, strongly typed IEnumerable<T> rather than IEnumerable so these sorts of errors are caught at compile time rather than run time.

As I’ve emphasized throughout this book, the compiler is your best friend. Use as many of its facilities as possible to catch coding errors at compile time rather than run time. Strongly typed languages such as C# rely upon the compiler to verify the integrity of the operations you perform on the types defined within the code. If you cast away the type and deal with general types such as System.Object rather than the true concrete types of the objects, you are throwing away one of the most powerful capabilities of the compiler. Then, if there is a typebased mistake in your code, and quality assurance does not catch it before it goes out the door, you can bet your customer will let you know about it, in the most abrupt way possible!

<span style="font-size:85%;"><span style="color: rgb(192, 192, 192);">Source Of Information : Apress Accelerated C Sharp 2010</span></span>

0 comments


Subscribe to Developer Techno ?
Enter your email address:

Delivered by FeedBurner