As promised in one of previous
posts - more about extension methods. Let's have a look at... LINQ!
You remember extension methods, whose simplest definition would be:
Extension methods are basically static methods that are callable through an instance syntax
[
The Evolution Of LINQ And Its Impact On The Design Of C#]
It seems like they were introduced in C# 3.0 to make LINQ work fully.
LINQ is a language feature allowing to query collections in a SQL-like manner (SELECT statement), something like:
var locals = from c in customers
where c.ZipCode == 91822
select new { FullName = c.FirstName + “ “ +
c.LastName, HomeAddress = c.Address };
So - where are extension methods here?
Well - the sample above is actually syntactic sugar, being equivalent to:
var locals =
customers
.Where(c => c.ZipCode == 91822)
.Select(c => new { FullName = c.FirstName + “ “ + c.LastName,
HomeAddress = c.Address });
Now, let's assume
customers are of type IEnumerable<Customer>.
IEnumerable<T> has only one method:
GetEnumerator<T>. This means that both
Where and
Select must be extension methods, which mix the SQL-like functionalities into all
IEnumerable<T>-s!
In fact the
Where method is very simple:
class EnumerableExtensions
{
public delegate T Func(A0 arg0);
public static IEnumerable Where(this IEnumerable source, Func predicate)
{
foreach (T element in source)
{
if (predicate(element)) yield return element;
}
}
}
It takes the
IEnumerable<T> source parameter - which is preceded by the
this keyword (so it's going to extend the
IEnumerable<T> type), and the
predicate delegate.
It can then use the
predicate to tell whether each
element in the
source satisfies the "WHERE clause".
Those, that do - are put into the resulting collection of the
Where method (using the
yield keyword).
So, basically the following:
customers.Where(c => c.ZipCode == 91822)
will result in calling the static
Where method against the
customers object, with the
Func<T, bool> predicate set to this anonymous method:
delegate {
if (c.ZipCode == 91822) yield return c;
}
Yep, that's what happened to the:
c => c.ZipCode == 91822
thing, which is actually a
lambda expression - another syntactic sugar in C# 3.0, on which more some other time.