Monday, August 21, 2006

 

Structural Conformance in C#

Most statically-typed OO languages (C++, Java, C#, etc.) implements what is called name-conformance between a class and an interface. A class is said to implement an interface if the class itself declares so by naming the implemented interface in its declaration. The compiler will then make sure that the class is indeed implementing the interface.
Another model of conformance is called structural conformance. Simply stated, a class is structurally conforming to an interface if it implements all the method declared in the interface, without any need to explicitly naming the interface (a more comprehensive definition of type conformance can be found here). So, given this C# code:
interface Ifc
{
void f( int x ) ;
}

class C
{
public void f( int x ) { ... }
}
C is structurally conforming to Ifc, but not name-conforming.
Structural conformance is not without dangers: a class may be accidentally conforming to an interface (for a slightly related problem: C++ templates use structural conformance to an implicit interface, that makes things more powerful and even more dangerous).
Still, structural conformance is extremely useful during maintenance and integration. Being able to retrofit a class under an interface, without any modification to the class, can be a real boon in many real-world situations (unavailability of source code being the most significant).
Lacking structural conformance, we usually end up with some kind of Adapter. The Adapter can also rename functions, and in some cases can add some [little] adaptation logic between calls. The trouble with the adapter is that we have to write one :-).
In the last few days I've spent some hours thinking about a library for Structural Conformance in C# 2.0 / 3.0 (aka Linq). It has been pretty easy to come up with a working solution that needs a little polishing. Right now, in the case above, I can write (in C# 3, using extension methods)
C obj = new C() ;
Ifc i = obj.As< Ifc >() ;
That gives a fast custom adapter between the C and Ifc. Fast means that there is no slow Invoke involved: the performance would be identical to an hand-crafted adapter.
My library can also handle renaming, although the syntax, right now, is somewhat lacking:
class C2
{
public void g( int x ) { ... }
}

C2 obj2 = new C2() ;
Ifc i2 = obj2.Renaming( "f", "g" ).As< Ifc >() ;
Renaming calls can be cascaded to rename more than one method. The syntax here is for C# 3.0, in C# 2.0 the call needs to be more explicit, like
C obj = new C() ;
Ifc i = StructuralAdapter< Ifc >.Wrap( obj ) ;
C2 obj2 = new C2() ;
Ifc i2 = StructuralAdapter< Ifc >.Renaming( "f", "g" ).Wrap( obj ) ;

Suggestions for improving the syntax are welcome.

I'm thinking about extending the concept of structural conformance to extension methods as well, but that will have to wait for a while. Right now, once I made my mind on the syntax, I'll have a little clean-up to do and then I'll make the library freely available here. Later on, I may write a short paper describing all this stuff with some more depth.

Caveat emptor: while true structural conformance is a compile-time, statically typed concept, this is a run-time, dynamically typed concept, so the Wrap / As functions can throw an exception if the class is not really conforming. On the other hand, previous works (mostly by Vincent Russo) to add structural conformance to Java and C++ in a type-safe way required changes to the respective compilers. As I consider this concept useful mostly in specific software integration / evolution situations, a dynamically typed solution that can be implemented as a library is not that bad :-).

Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?