Sunday, November 27, 2011

When to use delegates in C#

From: http://www.daniweb.com/software-development/csharp/threads/178715
When you have an interface with just one method:

interface IBlah {
    Foo JustOneMethod();
}

Use Lambdas instead of foreach loops:

NOT this:


List<Blah> blahs = new List<Blah>();
foreach (Bar elem in someOtherList)
{
     blahs.Add(elem.Prop);
}

Rather, this:

List<Blah> blahs = someOtherList
    .Select(elem => elem.Prop)
    .ToList();

NOT this:

List<Blah> blahs = new List<Blah>();
foreach (Bar x in someOtherList)
{
     if (x.Foo())
         blahs.Add(x.Prop);
}

Rather this:


List<Blah> blahs = someOtherList
    .Where(x => x.Foo())
    .Select(x => x.Prop)
    .ToList();

And this:

// Instead of INormer, have a delegate type Normer.
public delegate double Normer(Vector v);

// Let's make some functions that return normers:
public static Normer LNNormer(double n) {
    double recip = 1.0 / n;
    return v => Math.Pow(Math.Pow(v.X, n) + Math.Pow(v.Y, n), recip);
}

// instead of return a delegate, MaxNorm itself converts <strong class="highlight">to</strong> a delegate as needed
public static double MaxNorm(Vector v) {
    return Math.Max(v.X, v.Y);
}
// similarly for DiscreteNorm:
public static double DiscreteNorm(Vector v) {
    return v.X == 0.0 && v.Y == 0.0 ? 0.0 : 1.0;
}

// sorting is easy
public static void SortByMagnitude(List<Vector> vectors, Normer normer)
{
    vectors.Sort((u, v) => normer(u).CompareTo(normer(v)));
}

Calling the sort function:

SortByMagnitude(list1, MaxNorm);  // max-norm distance
SortByMagnitude(list2, DiscreteNorm);  // not good for sorting
SortByMagnitude(list3, LNNorm(2));  // euclidean distance
SortByMagnitude(list4, LNNorm(1));  // taxicab distance

No comments:

Post a Comment