Wednesday, October 17, 2007

LINQ - extension methods in action


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.

Sunday, October 7, 2007

Interview Questions: Constructors in C#


A good interview-type question: constructors in C#.


Here's a good one for an interview (whether you're the interviewer or the interviewee):

When declaring a constructor in the subclass, should I explicitly call the base class's constructor?
And if I don't - will the base class's constructor get called anyway?

That's basically what a discussion between my friend Marcin and me got down to...

If you've ever used Resharper (don't tell me you haven't!), you might have noticed that when you go:
class SubClass : BaseClass
{
public SubClass() : base()
{
// some code here
}
}
it will gray out base(), because it is redundant.

And it's true - because if the base constructor wasn't called, the object might not get fully initialized - and that would in a sense break the Liskov's Substitution Principle...

Actually - you do not have to "agree" for the base parameterless constructor to be invoked. You can choose a different one instead:
public SubClass() : base(5)
{
// some code here
}

However - if you look at this summary C# Constructors:
There must always be a "chain" of constructors which runs constructors all the way up the class hierarchy. Every class in the hierarchy will have a constructor invoked, although some of those constructors may not explicitly appear in the code.

All clear now, eh? ;)

Monday, October 1, 2007

Extension Methods in C# 3.0


This is actually "old stuff" today - but it is really cool: extension methods in C# 3.0 and mixins!


Ever wanted to raise a double to the power of another double without having to go like:
Math.Pow(10.343, 302.34);
?

Well, what do you say for that:
(10.343).RaiseToPower(302.34);


That would be very nice, and... it is possible, as long as:

  • you are using C# 3.0

  • you have implemented an extension method like this:

  •     public static class Powerade
    {
    public static double RaiseToPower(this double x, double y)
    {
    return Math.Pow(x, y);
    }
    }

    This is of course a quite useless example, but what extension methods are in essence is a way to implement mixins in C# 3.0: you can "mix in" some functionality to a type that is already there.

    More on mixins soon.