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.

Advertisements

6 thoughts on “Extending the Idea of Extension Methods

  1. 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.

  2. 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.

  3. 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.

  4. 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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s