The duck typing library is a .NET class library written in C# that enables duck typing. Duck typing is a principle 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. (For a detailed explanation, see the Wikipedia article.)
Beyond simple duck typing, this library has evolved to include different forms of variance in class members and other advanced features.
Download
This project is available to the public by Artistic License 2.0. Below are the most recent downloads.
Binaries: DuckTyping_0.9.30.zip (125.01 kb)
Source: DuckTyping_0.9.30_Source.zip (36.86 kb)
Features
I will try to keep this up to date, but I am constantly adding new features, so check the posts for any new features that haven't been added to this list.
- Casting a given object to a given interface that it does not implement by definition, but provides a compatible implementation of all its members. (This is done by dynamically generating a proxy type.)
- Covariance and contravariance - In the duck implementation, method parameters, return types, property types, and event handler delegate types may be different from that of the interface as long as they are convertible to one another, either through normal casting or duck typing.
- Delegate casting - A delegate of one type may be casted as a delegate of another type if the method parameters and return types are convertible to one another.
- Static class "casting" - An object of a given interface is generated that forwards calls to the static methods of a class. Thus, the behavior of a static class can be passed as an object instance.
- Variance between enumerations and strings - Casting an enumeration value to a string and vice versa. This is useful for variance of class members. For example, an interface method could take a string parameter and its duck implementation an enumeration value. Thus, the consumer of the interface object need not be coupled with the enumeration type.
- Performance - Although there is a performance hit when a new proxy type is generated, use of the casted object is virtually as fast to call as the object itself. Reflection.Emit is used to emit IL that directly calls the original object. No dynamic method invocation is used. Furthermore, red-black trees are used to catalog generated proxy types in memory for quick subsequent access. (Thanks to The NGenerics Team.)