Monday, 30 August 2010

Duck Typing and C#

The dynamic keyword in C# 4 (and the underlying DLR machinery making it possible) is amazing and powerful. Some people tend to get confused with Object, var and dynamic... but differences should be rather obvious:

  • var has nothing to do with dynamism, it's just compile time type inference (aka wrist friendliness).

  • Object is just that, everyone's ancestor that can be downcasted (with all its risks and inconveniences) to whatever we need

  • dynamic is pure dynamism, compiler assumes you know what you're doing when you declare something as dynamic and does not interfere. At runtime it will try to find the Method or Property that you're invoking-accessing, either using that object's implementation of IDynamicMetaObjectProvider, or resorting to Reflection. This is what we're used in languages like JavaScript, Python and so on... and is called Duck Typing



So dynamic and DLR are incredibly powerful, allowing us to mix the dynamic and static paradigms in the same language, but anyway, there are some limitations for which we'll need some extra help.

Let's say we have two compatible types (same public methods-properties) but while one of them implements an interface defining those semantics, the other one, for whatever reason (comes from a different code base for example) doesn't. Say we would like to use instances of both types in a piece of code. That's fine while that piece of code is dynamic, I mean, we're passing the object of one of the compatible types to a method expecting a dynamic parameter, but what happens if that method was implemented in a static fashion, expecting typed parameters (an interface)?
We would need to create a new class that implements that interface and redirects calls to the methods with the corresponding name in the initial class. Well, that's what dynamic proxies are for, intercepting and redirecting calls!.

For some odd reason, even in .Net 4, dynamic proxies are not part of the Framework (while Java has had them since the 1.3 times), so we would have to resort to one of the third party implementations out there (Castle, LinFu).
Castle DynamicProxy seems to be the most widely used, but I was already aware (I had toyed with it a bit some years ago) of the problem with its lack of documentation. Hopefully, this excellent tutorial encouraged me to jump onto it again.
Castle DP is arguably a powerful beast, but at first sight it didn't seem to provide out of the box support for what I needed (in principle you normally use it to intercept classes that already implement the common interface).
Googling for "C# and Duck Typing" I found a good article that explains how to accomplish what we want and shows me that I had read too fast the Castle samples.
He's using the CreateInterfaceProxyWithoutTarget. This is an interesting Proxy Generation method, as it does not need a class that already implements the interface, all the magic is in the interceptor. For this case Mauricio creates an interceptor that holds a reference to the proxied object, so we can invoke the corresponding method.

Proxy without target. This one is tricky. You don’t supply target implementation for the interface. Dynamic Proxy generates it for you at runtime, using interceptors to provide behavior for its methods.

The usage:

duck.As<IQuack>().Quack();

is very similar to the usage of this nice library that I had found some time ago (by the way, it also provides other useful functionalities like conversion between compatible delegates)
Note that this library has its roots in the pre-Extension Methods times, so that's why the syntax is uglier:

ICanAdd adder = DuckTyping.Cast<ICanAdd>(myAdder);

Back in 2008 the author (David Meyer) wondered if the advent of C# 4 would turn the library obsolete, as we've seen above, some parts of it are still useful, so I'll keep it in my programmer's toolkit.

You can see a usage sample here.
In order to compile it you'll need the DeftTech.DuckTyping.dll Assembly. You can get it all in this zip.

No comments:

Post a Comment