.Org Code for the social web, data management, and other interesting things.

23Nov/100

Attaching an Interface to a Class

There's a reminder that I need from time to time. Here, I'll share it with you: it is not possible to attach an interface to a class in C#. If the class does not declare that it implements the interface, then you have no way to attach that interface or its methods to an instance of the class. This is annoying when you're trying to program to an interface and realize For example, suppose we've defined the following interface and a couple classes:

This is a toy example, so the interface isn't really that useful. However, what if I want to treat ExplicitAdder and ImplicitAdder the same way? Both classes provide an Add method that accepts two integers and returns void. They're still different types, however, and ImplicitAdder doesn't declare that it implements IAdd even though the method signature matches the definition. This is by design, of course; it could be that the method in ImplicitAdder has nothing to do with IAdd and only matches the signature by accident. But it does make things difficult when you really want that class to implement IAdd:

This code shows the result of two different types of casting in an attempt to "attach" the IAdd interface to ImplicitAdder. Of course, casting ExplicitAdder to a variable of type IAdd works just fine. But when we use the 'as' keyword to perform the same conversion on ImplicitAdder, a null value is returned, indicating that this is an invalid cast. The explicit cast throws an InvalidCastException.

It is possible to execute the Add method using reflection on the type (or in C# 4, using the dynamic type), but this makes code fragile. What if the interface changes? The compiler cant' tell us to update the class. What if the class changes? The compiler can't tell us to update the reflection code. It just moves the problem into the run-time arena. This is a tactic to use when there's no other solution, but I don't like it much for software maintenance. No, the proper way to attach an interface to a class is by using a decorator of sorts:

Here we wrap the ImplicitAdder in a class that does implement IAdd. We pass a reference to an ImplicitAdder into the constructor and then use the wrapper object instead. This way the compiler can check all of our references at compile-time due to static typing.

5Aug/105

Generic Visitor Pattern in C#

The traditional model for application of the Visitor pattern, assuming that the visitable classes are immutable, is that the visitor class can produce data in one of two ways: it can either return data from the Visit() method, or it can aggregate data types inside the class. (The third option is to do both, of course.)

All well and good, but this model feels pretty limiting if you want to have multiple visitors that work on the same objects but produce different data types. In that case you can a) create as many versions of the visitor interface as you have data types to be returned, b) always aggregate within the visitor class, thus having to deal with mutable state inside the visitor, or c) always return object. Of those options, the first is tedious and the third is ugly. To my mind, both of them defeat the purpose of having the pattern in the first place. The second option is not bad, but I wanted something better than that.

Modern languages such as Java and C# include support for generics, so I tried my hand at writing a generic Visitor pattern that could be used on the same data structures by multiple visitor implementations that produce different data types. Using the new (well, newly old) features in C# 3.0, I was able to get a lot more. Let's start by looking at the IVisitor interface, which is parameterized by data type:

IVisitor is fairly straightforward when you think about it — we define a set of methods that accept an object of type R and produce an object of type R by visiting an IVisitable. This way we can write a single IVisitor interface for a data structure and then specialize it for a specific type later on, during the implementation. This is a nice improvement, but there's more we can do. C# 3.5 introduced extension methods, which allow us to attach methods to a wide range of classes at one time. Using a single extension method, we can eliminate the need for the second half of the traditional Visitor pattern, the Accept() method:

Now the Accept() method is available to be called on any class that implements IVisitable, as long as we provide an implementation of IVisitor. This means that we don't have to copy and paste the same code to every class that implements IVisitable any more! We can just call this method and .NET will wire it up.

The above definition makes use of a marker interface called IVisitable, but you could even restrict the application implicitly by which Visit() methods you define. In the case of a marker interface, you simply need to include a default method for visiting an IVisitable like so:

Which completes the generic visitor. Using a generalized class like this one allows us to program in a more functional and (hopefully) testable way. Plus, it's nice to actually use the new language features once in a while.

It's entirely possible that I've missed something in the implementation, so be sure to shout out in the comments if you've found a problem. Otherwise, enjoy your new generic Visitor in C#!

P.S. I should also give credit to some StackOverflow answers that suggested this approach, as well as a blog post on generic visitors in C# by Nicolas Penin, though I'm not aware of anyone else with an identical approach.

Update: Daniel Gröndal pointed out some issues with this approach in the comments. It turns out that the extension method does not work as I thought it did during my initial testing. Please read the comment thread for more details!