Monday, December 1, 2008

Java-like anonymous classes in C#

Sometime I want to implement an interface inplace with local variables context capturing. For interface IFoo

public interface IFoo
{
 double Estimate(int id);
}
I want to write something like
public IFoo Test()
{
    var k = 3.14D;
    return IFoo {
      double Estimate(int id) { return id * k; }
    };
}
Unfortunately upto C# 3.0 inclusive it isn't support yet. But we can emulate similar behaviour with lambda functions. First we create extension method which returns manually written adapter class. Such adapter takes lambda function for each interface method and use it as an implementation.
public static class IFooExtensions
{
 private struct IFooLambdaAdapter : IFoo
 {
  private readonly Func<int, double> foo;

  public IFooLambdaAdapter(Func<int, double> foo)
  {
   this.foo = foo;
  }

  public double Estimate(int id)
  {
   return foo(id);
  }
 }

 public static IFoo Implement(this IFoo @null, Func<int, double> foo)
 {
  return new IFooLambdaAdapter(foo);
 }
}
First parameter of Implement method used only to bind extension method to the interface. So we can use it in such way:
public IFoo Test()
{
 var k = 3.14D;
 return ((IFoo) null).Implement(id => id * k);
}

The code is pretty concise and leverages the power of lambda functions. Unfortunately the syntax of calling method with null reference is somewhat weird. Also such approach require manually coding adapter class instead of just relying on compiler generated one. As alternative we can use mocking frameworks approach to dynamically generate stubs.

No comments:

Post a Comment