A c# implementation of duck typing
Eric Lippert’s blogs (and his old blogs) have been my source to the inner working of VBScript and C# in the past decade. Recently, his blog on “What is ‘duck typing’?” has drawn lots of discussions and generated additional blogs from Phil Haack and Glenn Block. The discussion injects new ideas into my thoughts on programming by composition. I previously argued that interfaces are too big a unit for composition because they often live in different namespaces and only a few of the well-known interfaces are widely supported. I was in favor of lambdas (especially those that consume or return IEnumerable<T>) as composition unit. However, as I worked through my first end-to-end example, I found that lambdas are often too small (I will blog about this in details later).
Duck typing may solve the interface incompatibility problem in many situations. As described in Wikipedia, The name came from the following phrase:
“When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.”
If I would translate it into software engineering terms, I would translate it as:
The client expects certain behavior. If the server class has the behavior, then the client can call the server object even though the client does not explicitly know the type of the server objects.
That leads to the following implementation in a strongly-typed language like c#, consisting of:
- An interface defined by me to express my expected behaviors of duck, IMyDuck.
- An object from others that I want to consume. Let’s call its type OtherDuck.
- A function that checks if Duck has all the members of IMyDuck.
- A function (a proxy factory) that generates a proxy that implements IMyDuck and wrap around OtherDuck.
- In my software, I only bind my code to IMyDuck. The proxy factory is responsible for bridging IMyDuck and OtherDuck.
This implementation takes the expected behaviors as a whole. Except for the one time code generation for the proxy, everything else is strongly-typed at compile time. It is different to the “dynamic” in c# which implements late binding at the callsite.
I have checked my implementation into my Sky LINQ project under the c# project of SkyLinq.Composition. The name of the class is DuckTypingProxyFactory. The methods look like:
I have also provided an example called DuckTypingSample.cs in the SkyLinq.Sample project.
So when would duck-typing be useful? Here are a few:
- When consuming libraries from companies that implement the same standard.
- When different teams in a large enterprise each implement the company’s entities in their own namespace.
- When a company refactors software (see the evolution of asp.net for example).
- When calling multiple web services.
- I noticed the impromptu-interface project that does the same thing after I completed by project. Also, someone mentioned TypeMock and Castle in the comment of Eric’s log. So I am not claiming to be the first person with the idea. I am still glad to have my own code generator because I am going to use it to extend the idea of strongly-typed wrapper as comparing to data-transfer-objects.
- Also, nearly all Aspect-Oriented-Programming (AOP) and many Object-Relational-Mapping (ORM) frameworks have the similar proxy generator. In general, those in AOP frameworks are more complete because ORM frameworks primary concern with properties. I did looked at the Unity implementation when I implemented mine (thanks to the Patterns & Practices team!). My implementation is very bare-metal and thus easy to understand.