præclarum

Search:

Frank A. Krueger
Seattle, WA, United States

Recent Posts

Why Dictionary is Great - Dynamic List with Indice...
My 1 Minute Trial of VB 2008 Beta 2
Eben Moglen
Feynman my Hero
Mr. Gore acting as Philosopher
Assimilated by Win32
Times Reader makes reading on the web enjoyable ag...
A Naive Implementation of MapReduce in C#
Saturday
My 20 Minute Experience with WinFX

Extension Methods Make Code... Different

Thursday, August 30, 2007 Link

Funny. When I saw extensions methods first introduced, Anders kinda treated them as hacks. They were just a little trick to make Linq compile down to standards conforming CLI assemblies.

But I like them a lot because it occurred to me that they could be used to relieve a little pain point I have when using delegates. I can't seem to conjur up the words to explain the problem succinctly, so let's just jump straight to an example.

Suppose I have a bunch of objects that have a function to query whether they are in a good state. Here's some code for that object and a little function that displays all good objects.


class Obj {
int _val;
public Obj(int val) { _val = val; }
public int Value { get { return _val; } }
public bool IsGood()
{
return (_val % 2) == 0;
}
}

void DisplayGood()
{
List<Obj> objs = new List<Obj>();
foreach (Obj obj in objs.FindAll(delegate(Obj o) { return o.IsGood(); })) {
Console.WriteLine(obj);
}
}

END

This is pretty good, but there is one part I hate. This little bit: delegate(Obj o) { return o.IsGood(); } annoys the heck out of me. I wish I could just say Obj.IsGood, but that syntax isn't supported for some reason. Hmph. This isn't a huge problem, it's just an annoyance. Especially since C# 3.0 allows me to write something like objs.FindAll(o => o.IsGood()). That's pretty good.

But for fun, I could also restructure the code to take advantage of extension methods. I could do something like:


class Obj {
int _val;
public Obj(int val) { _val = val; }
public int Value { get { return _val; } }
}
static class ObjFs {
public static bool IsGood(this Obj o)
{
return (o.Value % 2) == 0;
}
}

void DisplayGood()
{
List<Obj> objs = new List<Obj>();
foreach (Obj obj in objs.FindAll(ObjFs.IsGood)) {
Console.WriteLine(obj);
}
}

END

Hehe. I used extension methods to create a class that extends Objs with useful stuff. In this case, it's our goodness query function. Then when I want to call FindAll, I only need to pass ObjFs.IsGood.

Hmm, that was a bit work to achieve only a little. Ah well, good practice.

Reader Comments

Post a Comment