Extension methods on lamdba expressions don’t work, unfortunately

Over the Christmas holidays, I thought I’d experiment with something I’d been thinking about a little – sorting a generic IList<T>. Now, before anyone gets huffy, I’m well aware of OrderBy in LINQ to Objects. However, sometimes you want to sort collections in-place, and as IList<T> provides random access, there’s no reason we shouldn’t be able to. Now, I do like the way that OrderBy allows multiple criteria to be specified, whether they should be applied in an ascending or descending fashion, and by way of just “compare by this projection” rather than having to actually implement the comparison yourself. I thought I could probably make use of those ideas again.

Unlike in LINQ to Objects, the sort would occur immediately, which means I couldn’t use quite the chained syntax of OrderBy(...).ThenBy(...).ThenByDescending(...) but my plan was to allow code like this:

List<Person> myList = …;

myList.SortBy((person => person.Name).Ascending(),
              (person => person.DateOfBirth).Descending(),
              (person => person.SocialSecurityNumber).Ascending());

Because each of the different output types involved might be different, that would only work for as many overloads as I’d implement. An alternative would be:

Comparer<Person> sorter = Comparer.By(person => person.Name)
                          .ThenByDescending(person => person.DateOfBirth)
                          .ThenBy(person => person.SocialSecurityNumber);

sorter.Sort(myList);

I did like the idea of the Ascending and Descending extension methods though, operating on Func<T1,T2>. Unfortunately, the dot operator doesn’t work on lambda expressions, even though the expression itself is implicitly convertible to Func<T1,T2>.

My plan isn’t entirely scuppered – the latter syntax will still work, and there are probably some alternatives I can work out. I think there are nice possibilities around extension methods and delegates though, and it’s a shame they’re not useful for lambda expressions. Ah well.

3 thoughts on “Extension methods on lamdba expressions don’t work, unfortunately”

  1. Well, I can get the following to compile:
    people.SortBy(
    people.Asc(p=>p.Name),
    people.Desc(p=>p.DateOfBirth),
    people.Asc(p=>p.SSN));

    Having IList extension methods (Asc/Desc) just to get the generic type inference is a bit hacky, but it works…

    SortBy(this IList list, params IComparer[] comparers)
    IComparer Asc(this IList list, Func selector)
    IComparer Asc(this IList list, Func selector, IComparer comparer)
    IComparer Desc(this IList list, Func selector)
    IComparer Desc(this IList list, Func selector, IComparer comparer)

    Like

  2. I’m aware that type inference doesn’t happen in a vacuum – but here there wouldn’t be a vacuum. There would be a set of possible types to attempt to convert to, as defined by the extension methods which accept that type of delegate.

    I certainly think it’s technically feasible for the future – I doubt that it’ll happen, but I suspect there are a few nice uses it could be put to.

    Jon

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s