Daniel Fortunov's Adventures in Software Development » Duck Typing
2 Comments- Add comment |
Back to Software Development Blog Written on 28-Jul-2009 by asquiIf it looks like a duck, and quacks like a duck, then it must be a duck!
“In computer programming, duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface.” — Wikipedia
With duck-typing an interface implementation is implicit once you have implemented the relevant members. .NET does not currently have any broad support for this, however, with the emergent dynamic language features, I wouldn't be surprised if this were supported natively by the runtime in the near future.
In the mean time, you can synthesise duck-typing via reflection, with a library such as this, which would allow you to do a duck-typed cast like this:
IDoo myDoo = DuckTyping.Cast<IDoo>(myFoo)
Interestingly, there is one small place where duck-typing is in use in C# today — the foreach operator. Krzysztof Cwalina states that in order to be enumerable by the foreach operator, a class must:
Provide a public method GetEnumerator that takes no parameters and returns a type that has two members: a) a method MoveMext that takes no parameters and return a Boolean, and b) a property Current with a getter that returns an Object.
Notice that he makes no mention of IEnumerable nor IEnumerator. Although it is common to implement these interfaces when creating an enumerable class, if you were to drop the interfaces but leave the implementation, your class would still be enumerable by foreach. Voila! Duck-typing!
But don’t take my word for it. Here’s some demo code to prove it:
public class Program { public static void Main() { foreach (int i in new DuckEnumerable()) Console.WriteLine(i); Console.ReadKey(); } } public class DuckEnumerable // Not IEnumerable { public Duck GetEnumerator() { return new Duck(); } } public class Duck // Not IEnumerator { private int n = 0; public int Current { get { return this.n; } } public bool MoveNext() { return (this.n++ < 10); } }
written on 28-Jul-2009
Tim Robinson [http://www.partario.com/blog/] says:
Obscure IEnumerator
This way they can avoid a heap allocation when GetEnumerator is called: the object returned from this method is just a struct that refers back to the parent collection. Because the C# code calls this struct's methods directly instead of through the IEnumerator interface they avoid a boxing operation.
Judging by the Reflector code for List
written on 16-Aug-2009
asqui says:
Wow, that's some pretty in-depth investigation into the kung-fu techniques of the Framework. Nice one Tim! Bart de Smet takes it a bit further and relates duck-typed foreach to LINQ (and explains why it doesn't quite work directly).