Retroactive Interfaces - Strong Duck Typing

Posted: 11/28/2007 3:28:39 AM

Anyone who has read about Ruby may have heard about Duck Typing; it allows any object to be passed into a method as long as the object has the properties/methods used by the originating method. If this were to be implemented in C# it would look something like:

public void Blah(object foo)
{
    Console.WriteLine(foo.Bar);
    Console.WriteLine(foo.Kung("Jackie Chan"));
}

And it would work completely fine at run-time as long as the object passed to the Blah method had a property called "Bar" and a method called "Kung" that took in a string as an argument. Unfortunately this won't work in C# because C# is a strongly typed language, "object" simply does not have a "Bar" property, nor a "Kung" method. Strong typing does have its advantages though, IntelliSense and compile time checking. If in Ruby you were to call the Blah method and it didn't have the appropriate properties and methods you would receive a run-time error. Run-time errors are bad because they make end-users cranky, which makes your boss cranky, which makes you cranky.

Strongly typed languages can have some of the benefits of this flexibility with Interfaces. Just create an IFoo interface with the needed properties and you're off to the races, right? Well, yeah, but only on objects that you have the ability to edit, which leaves you praying that the authors of your dependencies have your bizarre perfectly reasonable needs in mind (not likely).

For instance, I recently wrote a windows component that would listen for some events on a textbox and process the results. The only problem is I wanted to let the user hook up the component to either a TextBox or a ToolStripTextBox. Since those objects don't share a common interface, I have to have two separate properties on the component, a TextBox and a ToolStripTextBox and at run-time I have to throw an error if the user assigned a value to both properties (and remember, run-time error != desirable).

What I propose is the natural extension (pun intended) of Extension Methods -> Retroactive Interfaces. Simply put, I'd like to be able to tell the compiler that certain classes implement an interface, but do so from the interface, not from the class (because I may not be able to edit the class). I don't really care what the exact syntax is but I could imagine it going something like:

using System.Windows.Forms;

public Interface IText ImplementedBy TextBox, ToolStripTextBox
{
    string Text { get; set; }
    event EventHandler TextChanged;
}

This is if you wanted to be fairly precise about which classes implemented your new interface, but it would be also nice if to tell the compiler that you wanted any object that has the appropriate properties/methods/events to have it implement said interface. Such syntax could look like:

public Interface IText ImplementedByAllAppropriate  { ... }

And voilĂ , you now have the flexibility of Duck Typing and the compile time checking and IntelliSense of Strong Typing. I know bureaucracy can be a wildly beast, so Anders, if you're reading, I'm willing to grease proverbial wheels with $2,000,000 to get this feature in the next version of C#. (No, I don't have the $2,000,000 right now, but I'm working out a very lucrative deal with a rich Nigerian General)


Post Script: Like Extension Methods, Retroactive Interfaces aren't aimed at solving some unsolvable problem. You can definitely use the Adapter Pattern to wrap up the object and have the adapter class implement the needed interface. But lets be honest, its simply a pain in the ass, it takes time to write the adapter class and you have to explicitly create an adapter for every class you want to implement your interface (ImplementedByAllAppropriate, isn't really possible with an adapter). A Retroactive Interface is some syntatic sugar aimed at making developers lives easier.






Tags: Wishlist