Omer van Kloeten's .NET Zen

Programming is life, the rest is mere details

News

Omer van Kloeten's Facebook profile

Get Firefox

.NET Resources

Articles :: CodeDom

Articles :: nGineer

Culture

Projects

Extending the Idea of Extension Methods

I've had my fair share of disappointments when I found that the closest common denominator between types I wanted to use was object, leading me to write code in a level I did not like, like:

class A; // A and B are both imported classes with no 
class B; // common denominator except for object.

class MyListClass
{
    List<object> list = new List<object>();

    public void Add(object o)
    {
        this.list.Add(o);
    }
}

The above means that I have waved my compile-time (and if it stays like that, also my run-time) type safety in favor of being generic. There are solutions for this, but how about we take the new extension method syntax and play with it a bit? Now that you can add new features to types using extension methods, why not extend entire types by implementing interfaces?

this class MyClass : IFitsTheList
{
    // Extension methods here, if you like...
}

This way, we could revise MyListClass to:

class MyListClass
{
    List<IFitsTheList> list = new List<IFitsTheList>();

    public void Add(IFitsTheList o)
    {
        this.list.Add(o);
    }
}

Taking a complete type hierarchy and adding an Implemetation by Extension to the base class could prove to be a powerful tool.

Comments

Ayende Rahien said:

That would be a _really_ cool feature, but I don't believe that you will see it.

# April 13, 2007 4:59 AM

Joe Chung said:

Or you could make new classes to encapsulate A and B that support being added to your list.

class APrime : A, IFitsTheList

class BPrime : B, IFitsTheList

As long as A and B aren't sealed classes.

# April 13, 2007 5:41 AM

Omer van Kloeten said:

Joe - or that they're the root of a hierarchy you want to apply this interface too, which is the most common scenario in which this is most usable.

# April 13, 2007 6:19 AM

Joe Chung said:

If A' and B' are the roots of hierarchies of classes you want to apply this to, designating them as implementing IFitsTheList would make all your descendants qualify for inclusion in your list class.

Maybe I misunderstood your response though.

# April 13, 2007 9:47 PM

Omer van Kloeten said:

Joe - That's the original intention :)

# April 14, 2007 5:49 AM

Max said:

This would be nice to have, but you may be interested to know how Haskell solves this problem. It has a pretty unique feature called type classes. You can define one like this:

class Show a where

 showIt :: a -> String

And then at any point in your program declare an instance of the type class:

data Tree = Branch Tree Tree

         | Leaf Int

instance Show Tree where

 showIt (Leaf x) = show x

 showIt (Branch l r) = "(" ++ showIt l ++ "),(" ++ showIt r ++ ")"

Then your functions that want to showIt have type signatures like this:

myFunction :: (Show a) => a -> String

myFunction x = "The value is:\r\n" ++ (showIt x)

Where "(Show a) =>" is called a type class constraint. So this mechanism actually lets you attach behaviours to your "extension interfaces" too! This could be useful in C# when, say, your A and B provide some functionality but in slightly different ways (e.g. different method names) so you need to write a bit of adaptor logic to provide them with a uniform interface on IFitsTheList.

# April 15, 2007 7:43 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)