Writing

Other Sites

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.

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:

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.