IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

April (2018)

(1 item)

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

C# 3.0 - Extension Methods

Monday 26 September, 2005, 10:41 PM

One of the new C# 3.0 language features is 'extension methods'. The basic idea is that the set of methods available on an instance of a particular type is open to extension. In effect, we can add new methods to existing types.

Some people seem to think that this is stupid because, they claim, you can do the same thing with inheritance. However, the inheritance approach is rife with problems. Let's look at an example.

Supposing you are dealing with some type Foo that you don't own - maybe it's part of a 3rd party class library, so you don't get to modify the class. Suppose that this Foo class doesn't define a method called Bar. However, let's say you've written a method Bar that does something useful with a Foo instance. You might decide you'd like to be able to use the following syntax to invoke your Bar method:

void UseFoo(Foo f)
{
    f.Bar();
}

As an aside, my first reaction to this is always: why exactly do you want to do that? I tend to think that if you've written your own method that's not a part of Foo but which does stuff to Foo, then the code should probably reflect that. I think it's more honest, and easier for someone else to read if your code looks like this:

void UseFoo(Foo f)
{
    Bar(f);
}

However, requests for the former style seem to come up often enough that there's no denying the fact that some people really want to do it that way, apparently. It's not to my taste, but it takes all sorts.

Some people would use inheritance to 'solve' this. The inheritance approach looks like this:

public class MyBastardizedFoo : Foo
{
    public void Bar() { ... }
}

You can probably guess how I feel about this from the class name. Why do I dislike it? Well for starters there's the problem that it often doesn't work. Look at the first UseFoo above. Where is that Foo instance coming from? If we've been passed a Foo by code we don't control, then the fact that we've derived our own class from Foo doesn't help, because we've been passed an instance of the base class. If we try to cast to our derived class at this point, we'll just cause an exception. The inheritance approach can only be made to work in those cases where you get to create the object in the first place, which severely restricts its utility. (Sealed classes also get in the way. But even if all classes were unsealed, an idea that seems to appeal to some people, you're still left with the problem that you often don't get to create the instance.)

I also have a philosophical objection to using inheritance here. Even in the subset of scenarios where you get create the relevant object and can therefore make inheritance work I think it's the wrong thing to do. Specifically, if only reason you're using inheritance is the economy of the syntax in the first example, I believe that inheritance is the wrong way to go. That's because I think there's an important distinction between an operation that an object does, and some operation that is done with object where the object is a passive party.

Look at the two UseFoo methods above. They suggest different things. The first suggests that the Foo is going to do something because I just told it to. The second suggests that some action is being performed that needs to make use of the Foo, but which won't be performed by the Foo. When there's a choice of two different syntaxes that suggest two different things, I think it's best to pick the one that best represents what's actually happening.

The canonical example of getting this wrong can be found in the .NET Framework's String class. Time and time again I've seen beginners get confused by this:

void UseString(string s)
{
    s.ToUpper();
    ...
}

Seasoned .NET developers will see the problem instantly, but only because they've learned to spot it. (Actually, particularly seasoned developers will notice two problems. But getting into invariant cultures at this point would be a digression too far, even for me.)

Developers new to .NET tend to be surprised that calling ToUpper on a string doesn't convert it to upper case. And I think it's perfectly reasonably to be surprised. ToUpper looks like an imperative operation. Its form actively conceals the fact that it's really a function in the strict functional programming sense - it's has no side effects, it merely takes an input expression returns a result based on that input expression without modifying the input in any way. The input expression is the implicit this reference - the object on which ToUpper is invoked.

I think this form would have been more honest, and less likely to mislead:

String.ToUpper(input)

It's true that this would be more cumbersome, and would require more typing than what we've got today. But misleading code seems like a high price to pay for a little less typing - aren't we always being told that code will be read far more often than it is written? And even if you are convinced by the argument that a core class like String is sufficiently widely used that (a) it's worth the savings in this case because it affects everyone, and (b) everyone knows String so it doesn't matter that it's a special case, it still seems like the wrong thing to do in the general case.

I'm a big fan of code that does what it looks like it does. So if the first UseFoo above is a more accurate representation of what's happening than the second, you should use the first even if it means more typing. And of course if the second genuinely makes more sense, then by all means use it. But I suspect that the second style is wrong more often than it's right, not least because all of the examples I've seen put forward as arguments for making String unsealed would actually make more sense with the first syntax. Nonetheless, I'm sure there are some cases where the second version is the right one, in which case go for it! Except of course in C# 1 and 2.0 you often can't use the second one, because either you don't control the creation of the object in question, or the type in question happens to be sealed. Which brings us back to the fact that inheritance isn't the right solution here.

Dynamic language advocates will sometimes chip in at this point to claim that they have a 'better' solution. In Python you can dynamically add new methods to an instance:

def UseFoo(f):
    f.Bar = SomeMethod
    f.Bar()

Better my arse.

This does circumvent the "I didn't create the object" and the "the class is sealed" problems. So it's better in the sense that it gets the job done. But it suffers from being bleedin' 'orrible, which tends to put me off. Why's it horrible? It changes the instance that was passed in. Was my caller expecting me to edit the set of methods available on that instance? What if the caller was using this self same trick to add a Bar method of their own? We just broke their code. It seems pretty gross to me to go modifying someone else's object just for the syntactic convenience of the method I'm writing right now.

Isn't This Blog Entry Meant To Be About Extension Methods?

Extension methods offer an alternative solution for the scenarios where you really want to use the syntax in the first UseFoo above. They let you augment the set of method available on a reference of any type, even when you have no control over the type or instance in question. Morever, they do so in a way that can be completely self-contained, which seems a lot cleaner to me than either inheritance or the dynamic language trick of fiddling with the instance.

Despite being cleaner than the alternatives, I still think the following is pretty unpleasant, but it does illustrate how to write and use an extension method. The Print method extends the String class, which is signified by the extra this keyword on the first parameter. This method enables us to pretend that variables of type String have a Print instance method, which we take advantage of in the Main method.

static class Program
{
    static void Main(string[] args)
    {
        string s = "Hello, world";
        s.Print();
    }

    static void Print(this string s)
    {
        Console.WriteLine(s);
    }
}

OK, so that made me feel slightly dirty, and not in a good way...

That said, it grosses me out less than the dynamic language approach of dynamically adding new methods to the string object that was passed in... At least with this extension method, the unpleasantness is all strictly in the privacy of my own class. That Print is private so nobody else has to put up with it.

Just to be clear, this is only an alternate syntax. That line where we call the Print method on the string instance is exactly equivalent to the following code:

Print(s);

Extension methods are simply methods that can be called using either style. So looking back at our original two UseFoo examples, if Bar were an extension method you could use either syntax and it would compile down to the same thing.

While the Print method here happens to be private, you can also define these things as public methods on public types. (Both the method and the declaring class must be static.) At this point any code with a using statement bringing in the namespace containing the types in question will have access to these methods. This is where I start to get a little more nervous. Let's suppose some joker decides to write this:

namespace System
{
    public static class Evil
    {
        public static void Print(this object s)
        {
            Console.WriteLine(s);
        }
    }
}

Since almost all C# source files have a using System; declaration, this extension method is effectively going to be available globally - it augments the set of methods available on the base Object type. Indeed, Peter Ritchie drew an apt analogy on the DOTNET-CX list:

"Extension methods seems to be a hack to recover from lack (or removal, considering C++ roots) of nonmember functions"

They certainly feel somewhat similar in usage, although the syntax is rather funkier. The fact that the name of the class that defines the function is nowhere to be seen at the call site (at least not in the source code) does rather suggest that these things really don't want to be class members. And this introduces a couple of problems: (1) how are you meant to discover what extension methods are available to you, and (2) how are you meant to know where a function call will go from looking at the code? The answer to (1) is probably a combination of documentation idioms and IntelliSense. (2) I'm not so sure about.

While I hope it's fairly obvious that defining your own types in the System namespace or its descendants is a Bad Thing if you're not Microsoft, the more subtle and worrying possibility is that class libraries might 'helpfully' put such extension methods into their own top-level namespaces. For example, if I do a using FooSoft.FooLib;, I might get more than just the classes I wanted to use from FooLib - I might pick up a load of extension methods I didn't particularly want, but which the authors of FooLib thought I wouldn't be able to live without. Let's hope everyone follows Microsoft's lead and segragates these things into separate namespaces - the extension methods that form part of LINQ are all in System.Query for example, so you won't get them unless you ask for them. Then again, that's not the only stuf in that namespace so maybe we're already in trouble...

In practice I suspect I'm being unduly nervous. I think my slightly negative reaction is similar to the feeling I first got when I saw non-member functions in C++ proposed as being better than member functions in certain scenarios. "But that's not OO," I spluttered in my (relatively) youthful idealism. These days I've learned to be suspicious of any practice whose sole justification is that it's "more object-oriented." If that's the only reason something has been done in a particular way, it's probably a code smell. OO is just a toolkit, and for certain jobs, other styles (e.g. functional programming) sometimes offer better tools. Of course, if being "more object-oriented" offers specific advantages in your scenario, then more power to you, but being OO should not be an end in itself. The fact is that not all methods belong in classes. You can see this from the way some classes are really nothing more than namespaces in disguise. (Take a look at System.Math for example.)

Attached Properties and Attached Events

C# 3.0 currently only offers extension methods. It does not allow us to bolt properties or events onto existing types. I find this particularly interesting because one of my favourite technologies, WPF (aka Avalon) does the opposite. WPF doesn't offer extension methods, but you can define 'attached' properties and events, which can be attached to other objects. And I'm a big fan of these.

These crop up all over the place in WPF. UI building tends to involve lots of orthogonal concepts. For example, layout is something that you tend to want to apply to all visual elements. A good UI framework should let you introduce new layout managers that can work across all existing element types without needing to rewrite those types. Input is another example. Mouse and keyboard input apply to everything, as does ink. And while you could argue that new input mechanisms don't come along as often as new layout systems, they still appear from time to time. Ink is a relative newcomer. My new laptop has an integrated fingerprint reader, which seems to me like a input device that is very different in character from keys, mouse, pen, voice, or joystick. (Right now its tied to the login UI, but I can imagine scenarios where it would be useful for applications to be able to use it.) Text handling is yet another cross-cutting feature - you want to apply text styling properties to more or less anything, since most controls can end up showing text.

In short, when you're building UIs, you tend to want to be able to plug together arbitrary combinations of features. This makes single inheritance particularly ill-suited to UI frameworks. Not that it's impossible to devise UI frameworks that use single inheritance - I think that the Windows Forms does a pretty good job of it, and its System.Windows.Forms.Control class is a tour de force as base classes go. But it's not hugely open to certain kinds of extension. The supported layout styles are baked in to this base class, making it custom layout managers feel like second class citizens. Microsoft can add new layout styles by adding new features to Control, but what about my layout manager? Likewise, the set of supported input systems is prescribed. Windows Forms does what it does well, but it sometimes feels like a strait jacket once you're used to WPF.

You could use this as an argument for multi inheritance. Certainly MI can enable orthogonal inheritance-based composition. But why bring inheritance into it if all you actually wanted was orthogonal composition? As I've said in the past, one of the great tragedies of the current crop of mainstream languages is the bizarre and awkward construct we call inheritance. It conflates two very important but really rather different concepts: reuse and polymorphism. When you stop and think about it, having one solution that attempts to address these two requirements is a bit bizarre. The last thing we need is a greater emphasis on inheritance, so I'm not about to lobby for MI in .NET. Particularly not now that I've spent some time seeing non-inheritance-based compositional reuse in action, in the form of attached properties and events.

I've already gone on long enough here, and this part is incidental to the main topic, so I won't go into a detailed explanation of attached properties and events. But I can't leave it hanging without an example.

Layout is the first place most people come across attached properties. WPF defines various 'panels' which arrange their contents in certain ways. These range from the very simple explicit positioning offered by Canvas, through simple automated layouts like StackPanel up to fairly sophisticated table-style layout with Grid. For most layout styles, the elements being arranged may need to pass information to the panel in order to be arranged correctly. Elements on a Canvas must specify their exact position. Elements in a Grid need to indicate where they appear on the grid coordinate system. Elements in a DockPanel must indicate which edge of the panel they wish to use. A simple nesting approach won't always work - children of a grid may choose to span multiple grid cells, for example.

Children indicate their requirements to the panel through properties. But each panel requires different properties. In a world of attached properties, this isn't a problem - each panel type defines the properties its children will need. E.g.:


Hello!

If I want to introduce a new layout, it will work in exactly the same way as the built-in panels - I can define my own attached properties. No more looking like a second class citizen.

In this case the attached properties are effectively just annotations. They feel a bit like .NET custom attributes here in that they're just bits of information attached to a particular element, and which will be processed by some container rather than by the target element. However, it doesn't have to be this way - it is quite possible to define an attached property which actively does stuff to the target element if you want.

Likewise, events can be attached. An element doesn't need to know of a particular event type in order for that event to be raised on that element. So input devices can route whatever input handling events they see fit through any UI element without needing any help from the element. This makes it possible for new input devices to be introduced as time goes on.

I've come to like attached events and properties more and more as I've become used to them. Maybe in time I'll feel the same way about extension methods.

Copyright © 2002-2024, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk