Welcome to

Magenic Technologies Community Blog

Sign in | Join | Help

Aaron's Technology Musings

Who let this guy on the podium?

Introducing DuckCallLib - An Extension Method to (almost) enable Duck Typing in C#

Scratching an itch today, thinking about code I have written in the past to attempt to do duck calls in C# (that is, call a named method without explicitly knowing that it even supports the method) - I decided, what the heck, why not just write the extension method over object required to do duck calls.

So, with great fanfare (ha!) - I have published DuckCallLib on codeplex (codeplex.com/duckcalllib).  This is hardly a big project, more like a handy piece of code that allows you to not have to dig through reflection yourself every time you need to handle a duck typing scenario from C# code.

Let say we have a simple class, such as this:

  public class RandomClass
  {
    public int AddNumbers(int op1, int op2)
    {
      return (op1 + op2);
    }

    public double AddNumbers(double op1, double op2)
    {
      return (op1 + op2);
    }
  }

Now, lets say we want to call "AddNumbers" without knowing anything about RandomClass:

      object rndClass = new RandomClass();
      object two = rndClass.DuckCall("AddNumbers", new object[] { 1, 1 }, null);
      Assert.IsTrue((int)two == 2);

Or, a more complex and meaningful scenario, we want try to make a call, but have a lambda get invoked if the method is missing:

      Func<object,string,object[],object> methodMissingHandler =
        (source, methodName, theParameters) =>
          (decimal)theParameters[0] +
          (decimal)theParameters[1];
      object rndClass = new RandomClass();
      object two = rndClass.DuckCall(
        "AddNumbers",
        new object[] { 1m, 1m },
        methodMissingHandler );
      Assert.IsTrue((decimal)two == 2m);

As you can see, ruby this isn't.  It is not nearly as clean syntactically as I would like it to be.  However, given the current limitations of the C# language, this is what I have been able to come up with.  If anyone has other ideas, I certainly encourage anyone to send em my way.

Enjoy!

Published Thursday, June 26, 2008 1:38 PM by Anonymous

Filed under:

Comments

# re: Introducing DuckCallLib - An Extension Method to (almost) enable Duck Typing in C# @ Thursday, June 26, 2008 12:11 PM

I wouldn't say it is duck typing, I would say it's exactly what's called late binding.

To be proper duck typing it has to be typesafe.

Something like this:

interface IHasAddNumbers

{

   int AddNumbers(int x, int y);

}

int sum = myRandomObject.Duck<IHasAddNumbers>().AddNumbers(10,20);

The extension method Duck<T> should create a 'proxy' instance that implements interface T, but every method call is forwarded to the real instance similarly named methods.

Obviously, it has to use Reflection.Emit. It is not too complex, I have done that myself for the other purpose.

mihailik

# re: Introducing DuckCallLib - An Extension Method to (almost) enable Duck Typing in C# @ Thursday, June 26, 2008 12:12 PM

BTW, the latest VB has similar feature already.

mihailik

# re: Introducing DuckCallLib - An Extension Method to (almost) enable Duck Typing in C# @ Thursday, June 26, 2008 12:24 PM

I was under the impression that duck typing was specifically waiting to test the types at runtime, and throw missingMethod (or handle somehow) when nothing matches.

I am certainly doing that by checking the parameters in the extension method.  That said, I am not doing anything that checks up the chain yet for interfaces - it is really a naive implementation at this point.

Anonymous

# re: Introducing DuckCallLib - An Extension Method to (almost) enable Duck Typing in C# @ Thursday, June 26, 2008 1:56 PM

The thing I am proposing should do the magic at runtime too.

I guess I have to clarify what is that I am talking about.

Let say you want to invoke a certain method on an unkown object. Let it be AddNumbers method. First thing you do, you create a 'fake' interface IHasAddNumbers which has method(s) you want to call. Of course the unknown object does not implement that interface. Here comes the 'magic' library, that can create a facade that implements the interface and forward the call to the proper method.

In this way the code is typesafe (still may fail at runtime if the method is not found). And, it is really performant, because the reflection hit is paid only once, because the 'facade' code is generated and then just used.

Here is the facade pseudo-code that the magic library would generate:

class RandomClassFacade : IHasAddNumbers

{

 private readonly RandomClass instance;

 public RandomClassFacade(RandomClass instance)

 { this.instance = instance; }

 public int AddNumbers(int x, int y)

 { return instance.AddNumbers(x,y); }

}

mihailik

# re: Introducing DuckCallLib - An Extension Method to (almost) enable Duck Typing in C# @ Thursday, June 26, 2008 2:02 PM

I think I see what you are doing here.  I would prefer not to get into reflecting code dynamically though - it seems as though I could possibly memoize the reflection somehow and create a vtable of sorts so I don't have to re-do the reflection for repeated calls.  I think you suggest doing that by dynamically creating an interface - which seems like a good way to do it.

Short of that, somehow even just storing references to the appropriate map between a given set of names and parameters to the right methodinfo might do the trick too.

Anonymous

# re: Introducing DuckCallLib - An Extension Method to (almost) enable Duck Typing in C# @ Thursday, June 26, 2008 4:04 PM

Yes, dynamically creating *implementation* of interface. The interface itself is statically defined. The whole idea is to eliminate using of strings.

mihailik

# re: Introducing DuckCallLib - An Extension Method to (almost) enable Duck Typing in C# @ Friday, June 27, 2008 3:04 AM

Hi Mihailik, You would have to statically create a lot of interfaces to emulate true Dynamic Duck Typing in the case were a method conditionally uses attributes (like this for example: http://en.wikipedia.org/wiki/Talk:Duck_typing#DuckDecoy_Example). The alternative would be to require objects to have all the attributes that _could_ be used. - Paddy.

Paddy3118

# re: Introducing DuckCallLib - An Extension Method to (almost) enable Duck Typing in C# @ Friday, June 27, 2008 11:14 AM

Hi Paddy,

Depends on why you need that duck typing in the first place.

If you want to call ocasionally one or two methods in 'duck way', you probably would want to create an interface, even if duck-fake interface. In this way you kind of manifest, what does that mean 'to behave like a duck'.

If you want to call a lot of loose-typed methods, and be totally tolerant to every kind of missing stuff or type conversions, or not completely compatible signatures, you don't want to use C# in the first place.

mihailik

New Comments to this post are disabled
Powered by Community Server, by Telligent Systems