All posts by jonskeet

Mad props to @arcaderage for the "Princess Rescue" image - see https://toggl.com/programming-princess for the full original

Inheritance Tax


Introduction

There aren’t many technical issues that my technical lead (Stuart) and I disagree on.
However, one of them is inheritance and making things virtual. Stuart tends to favour
making things virtual on the grounds that you never know when you might need to inherit from
a class and override something. My argument is that unless a class is explicitly designed
for inheritance in the first place, you can get into a big mess very quickly. Desiging a
class for inheritance is not a simple matter, and in particular it ties your
implementation down significantly. Composition/aggregation usually works better in
my view. This is not to say that inheritance isn’t useful – like regular expressions,
inheritance of implementation is incredibly powerful and I certainly wouldn’t dream of
being without it. However, I find it’s best used sparingly. (Inheritance of interface is a
different matter – I happily use interfaces all the time, and they don’t suffer from the
same problems.) I suspect that much of my wariness is due to a bad experience I had with
java.util.Properties – so I’ll take that as a worked example.

Note: I’ll use the terms “derived type” and “subclass” (along with their related
equivalents) interchangably. This post is aimed at both C# and Java developers, and I can’t
get the terminology right for both at the same time. I’ve tended to go with whatever sounds
most natural at the time.

For those of you who aren’t Java programmers, a bit of background about the class.
Properties represents a “string to string” map, with strongly typed methods
(getProperty and setProperty) along with methods to save and
load the map. So far, so good.

Something we can all agree on…

The very first problem with Properties itself is that it extends
Hashtable, which is an object to object map. Is a string to string map
actually an object to object map? This is actually a question which has come up a lot
recently with respect to generics. In both C# and Java, List<String>
is not viewed as a subtype of List<Object>, for instance. This can
be a pain, but is logical when it comes to writable lists – you can add any object
to a list of objects, but you can only add a string to a list of strings. Co-variance
of type parameters would work for a read-only list, but isn’t currently available in C#.
Contravariance would work for a write-only list (you could view a list of objects as a list
of strings if you’re only writing to it), although that situation is less common, not to
mention less intuitive. I believe the CLR itself supports non-variance, covariance and
contravariance, but it’s not available in C# yet. Arguably generics is a complicated
enough topic already, without bringing in further difficulties just yet – we’ll have to
live with the restrictions for the moment. (Java supports both types of variance to
some extent with the ? extends T and ? super T syntax. Java’s
generics are very different to those in .NET, however.)

Anyway, java.util.Properties existed long before generics were a twinkle
in anyone’s eye. The typical “is-a” question which is usually taught for
determining whether or not to derive from another class wasn’t asked carefully enough in
this case. I believe it’s important to ask the question with Liskov’s Substitution Principle
in mind – is the specialization you’re going to make entirely compatible with
the more general contract? Can/should an instance of the derived type be used as if it were
just an instance of the base type?

The answer to the “can/should” question is “no” in the case of Properties, but
in two potentially different ways. If Properties overrides put (the
method in Hashtable used to add/change entries in the map) to prevent non-string
keys and values from being added, then it can’t be used as a general purpose Hashtable
– it’s breaking the general contract. If it doesn’t override put then a
Properties instance merely shouldn’t be used as a general purpose
Hashtable – in particular, you could get surprises if one piece of code added
a string key with a non-string value, treating it just as a Hashtable, and then
another piece of code used getProperty to try to retrieve the value of that key.

Furthermore, what happens if Hashtable changes? Suppose another method is added which
modifies the internal structure. It wouldn’t be unreasonable to create an add method
which adds a new key/value pair to the map only if the key isn’t already present. Now, if
Properties overrides put, it should really override add as
well – but the cost of checking for new methods which should potentially be overridden every time a
new version comes out is very high.

The fact that Properties derived from Hashtable
also means that its threading mechanisms are forever tied to those of Hashtable.
There’s no way of making it use a HashMap internally and managing the thread
safety within the class itself, as might be desirable. The public interface of
Properties shouldn’t be tied to the fact that it’s implemented using
Hashtable, but the fact that that implementation was achieved using
inheritance means it’s out in the open, and can’t be changed later (without abandoning
making use of the published inheritance).

So, hopefully we can all agree that in the case of java.util.Hashtable and
java.util.Properties at least, the choice to use inheritance instead of aggregation
was a mistake. So far, I believe Stuart would agree.

Attempting to specialize

Now for the tricky bit. I believe that if you’re going to allow a method to be overridden
(and methods are virtual by default in Java – fortunately not so in C#) then you need to document
not only what the current implementation does, but what it’s called from within the rest of
the class. A good example to demonstrate this comes from Properties again.

A long time ago, I wrote a subclass of Properties which had a sort of hierarchy.
If you had keys "X", "foo.bar" and
"foo.baz" you could ask an instance of this hierarchical properties type for a
submap (which would be another instance of the same type) for "foo". The returned
map would have keys "bar" and "baz". We used this kind of hierarchy
for configuration. If you’re thinking that XML would have been a better fit, you’re right.
(XML didn’t actually exist at the time, and I don’t know if there were any SGML libraries around
for Java. Either way, this was a reasonably simple way of organising configuration.

Now the question of whether or not I should have been deriving from Properties
in the first place is an interesting one. I don’t think there’s any reason anyone couldn’t or
shouldn’t use an instance of the PeramonProperties (as it was unfortunately called)
class as a normal Properties object, and it certainly helped when it came to other
APIs which wanted to use a parameter of type Properties. As it happens, I believe
we did run into a versioning problem, in terms of wanting to override a method of
Properties which only appeared in Java version 1.2, but only when compiling against
1.2. It’s certainly not crystal clear to me now whether we did the right thing or not – there
were definite advantages, and it wasn’t as obviously wrong as the inheritance from Hashtable
to Properties, but it wasn’t plain sailing either.

I needed to override getProperty – but I wanted to do it in the simplest possible way.
There are two overloads for getProperty, one of which takes a default value and one
of which just assumes a default value of null. (The default is returned if the key isn’t
present in the map.) Now, consider three possible implementations of getProperties in
Properties (get is a method in Hashtable which returns
the associated value or null. I’m leaving aside the issue of what to do if a non-string
value has been put in the map.)

First version: non-defaulting method delegates to defaulting

public String getProperty (String key)
{
    return getProperty (key, null);
}
    
public String getProperty (String key, String defaultValue)
{
    String value = (String) get(key);
    return (value == null ? defaultValue : value);
}

Second version: defaulting method delegates to non-defaulting

public String getProperty (String key)
{
    return (String) get(key);
}
    
public String getProperty (String key, String defaultValue)
{
    String value = getProperty (key);
    return (value == null ? defaultValue : value);
}

Third version: just calling base methods

public String getProperty (String key)
{
    return (String) get(key);
}

public String getProperty (String key, String defaultValue)
{
    String value = (String) get(key);
    return (value == null ? defaultValue : value);
}

Now, when overriding getProperty myself, it matters a great deal what the implementation
is – because I’m likely to want to call one of the base overloads, and if that in turn calls
my overridden getProperty, we’ve just blown up the stack. An alternative is to override
get instead, but can I absolutely rely on Properties calling get?
What if in a future version of Java, Hashtable adds an overload for get which
takes a default value, and Properties gets updated to use that instead of the signature
of get that I’ve overridden?

There’s a pattern in all of the worrying above – it involves needing to know the implementation
of a the class in order to override anything sensibly. That should make two parties nervous – the
ones relying on the implementation, and the ones providing the implementation. The ones
relying on it first have to find out what the implementation currently is. This is hard enough
sometimes even when you’ve got the source – Properties is a pretty straightforward
class, but if you’ve got a deep inheritance hierarchy with a lot of interaction going on it can
be a pain to work out what eventually calls what. Try doing it without the source and you’re in
real trouble). The ones providing the implementation should be nervous because they’ve now effectively
exposed something which they may want to change later. In the example of Hashtable providing
get with an overload taking a default value, it wouldn’t be unreasonable for the
authors of Properties to want to make use of that – but because they can’t change the
implementation of the class without potentially breaking other classes which have overridden
get, they’re stuck with their current implementation.

Of course, that’s assuming that both parties involved are aware of the risks. If the author
of the base class doesn’t understand the perils of inheritance, they could easily change the
implementation to still fulfill the interface contract, but break existing subclasses. They
could have all the unit tests required to prove that the implementation was, in itself, correct –
but that wouldn’t help the poor subclass which was relying on a particular implementation.
If the author of the subclass doesn’t understand the potential problems – particularly if
the way they first overrode methods just happened to work, so they weren’t as aware as they
might be that they were relying on a specific implementation – then they may not
do quite as much checking as they should when a new version of the base class comes out.

Does this kill inheritance?

Having proclaimed doom and gloom so far, I’d like to emphasise that I’m not trying
to say that inheritance should never be used. There are many times when it’s fabulously
useful – although in most of those cases an interface would be just as useful from a client’s
point of view, possibly with a base class providing a “default implementation” for use where
appropriate without making life difficult for radically different implementations (such as
mocks :)

So, how can inheritance be used safely? Here are a few suggestions – they’re not absolute
rules, and if you’re careful I’m sure it’s possible to have a working system even if you
break all of them. I’d just be a bit nervous when trying to change things in that state…

  • Don’t make methods virtual unless you really need to. Unless you can think of a reason
    why someone would want to override the behaviour, don’t let them. The downside of this
    is that it makes it harder to provide mock objects deriving from your type – but interfaces
    are generally a better answer here.
  • If you have several methods doing a similar thing and you want to make them virtual,
    consider making one method virtual (possibly a protected method) and making all
    the others call the virtual method. That gives a single point of access for derived classes.
  • When you’ve decided to make a method virtual, document all other paths that will call
    that method. (For instance, in the case above, you would document that all the similar
    methods call the virtual one.) In some cases it may be reasonable to not document the
    details of when the method won’t be called (for instance, if a particular
    parameter value will always result in the same return value for one overload of a method,
    you may not need to call anything else). Likewise it may be reasonable to only document
    the callers on the virtual method itself, rather than on each method that calls it.
    However, both of these can affect an implementation. This documentation becomes
    part of the interface of your class – once you’ve stated that one method will call
    another (and implicitly that other methods won’t call the virtual method) any
    change to that is a breaking change in the same way that changing the acceptable parameters
    or the return value is. You should also consider documenting what the base implementation
    of the method does (and in particular what other methods it calls within the same class) –
    quite often, an override will want to call the base implementation, but it can be difficult
    to know how safe this is to do or at what point to call it unless you know what the
    implementation really does.
  • When overriding a method, be very careful which other methods in the base class you
    call – check the documentation to make sure you won’t be causing an infinitely
    recursive loop. If you’re deriving from one of your own types and the documentation
    isn’t explicit enough, now would be a very good time to improve it. You might also
    want to make a note in the base class that you’re overriding the method in the specific
    class so that you can refer to the overriding method if you want to change the base class
    implementation.
  • If you make any assumptions when overriding a method, consider writing unit tests to document
    those assumptions. For instance, if you assume that calling method X will result in a call to
    your overridden method Y, consider testing that path as well as the path where method Y is
    called directly. This will help to give you more confidence if the base type is upgraded to
    a newer version. (This shouldn’t be considered a replacement for careful checking when
    the base type is upgraded to a new version though – indeed, you may want to add extra tests
    due to an expanding API etc.)
  • Take great care when adding a new virtual method in Java, as any existing derived class which
    happens to have a method of the same name will automatically override it, usually
    with unintended consequences. If you’re using Java 1.5/5.0, you can use the @Override
    annotation to specify that you intend to override a method. Some IDEs (such as Eclipse) have
    options to make any override which doesn’t have the @Override annotation result
    in a compile-time error or warning. This gives a similar degree of safety to C#’s requirement
    to use the override modifier – although there’s still no way of providing a “new”
    method which has the same signature as a base type method but without overriding it.
  • If you upgrade the version of a type you’re using as a base type, check for any changes in
    the documentation, particularly any methods you’ve overridden. Look at any new methods which
    you’d expect to call your overridden method – and any you’d expect not to!

Many of these considerations have different effects depending on the consumer of the type.
If you’re writing a class library for use outside your development team or organisation,
life is harder than in a situation where you can easily find out all the uses of a particular
type or method. You’ll need to think harder about what might genuinely be useful to override
up-front rather than waiting until you have a need before making a method virtual (and then
checking all existing uses to ensure you won’t break anything). You may also want to give more
guidance – perhaps even a sample subclass – on how you envisage a method being overridden.

Conclusion

You should be very aware of the consequences of making a method virtual. C# (fortunately in my view)
makes methods non-virtual by default. In an interview
Anders Hejlsberg explained the reasons for that decision, some of which are along the same lines as
those described here. Java treats methods as virtual by default, using Hotspot to get round the performance
implications and largely ignoring the problems described here (with the @Override annotation
coming late in the day as a partial safety net). Like many powerful tools, inheritance of implementation
should be used with care.

Worst product names ever?

A while ago, I decided that EasyMock.NET wasn’t quite up to scratch, and I was going to try to write a replacement. I’m not doing much .NET development at the moment, so it’s not an issue any more (and when I go back to .NET I’ll look at Rhino Mocks which sounds promising). However, I did get as far as picking a name for the new project. I settled on PowerMock in the end, but went through a pun worthy of Simon Tatham first…

Firstly, it would have to start with “N” wouldn’t it? NUnit, NCover etc… Well, what sounds a bit like mocking something, and starts with “N”. How about “NSult”, to be pronounced “insult”?

Next, suppose we wanted a new unit test system at the same time. Maybe something like TestNG but for .NET. Something to judge your code and decide whether it was good or not. Ooh, that sounds a bit like a court-room drama. How about “NJury”?

Of course, they work best when you put them together – adding NSult to NJury…

Sorry. I’ll go to bed now, promise.

Bringing Subversion and Fitnesse together

I’ve recently started working with Subversion (a version control system) and FitNesse (the Fit acceptance testing framework based in a wiki). FitNesse has a primitive version control system built into it, where it builds zip files of previous versions of pages. It’s all a bit messy though, and it’s not likely to be the version control system used by the rest of your source code. Why wouldn’t you want your acceptance tests in the same repository you use for the rest of your source and tests?

So, arming myself with JavaSVN (a pure Java Subversion client library) I went looking
at the FitNesse source code. I’m sorry to say it’s not everything I’d hoped for – lots of methods declared to just throw Exception, using streams with no try/finally blocks and (I suspect) a rather gaping potential for things to go seriously wrong if someone commits a page at the same time as someone else deletes it. However, life goes on – fortunately I was able to find the entry point I needed fairly quickly.

In this case, it was fitnesse.wiki.FileSystemPage, which dealt with both the writing of the “plain” contents/metadata files, along with the versioning. It was only a matter of a few hours to refactor that to allow the versioning piece to be pluggable. Adding Subversion support took another few hours, and the result works reasonably well. A few things to note:

  • I could possibly have used an existing plugin point instead of creating a versioning system off FileSystemPage.
    I didn’t know that at the time, and I’m not sure how much it would have helped me. I’m not sure whether JavaSVN would have
    let me get away with making changes to the repository without having a working copy at all, but if so that would have been
    quite a nice solution. There’s no real need for a directory hierarchy – just a file per page, and Subversion properties to
    store the FitNesse metadata. With the sort of load I’m expecting the server at work to have, performance wouldn’t have been
    an issue, and it would quite possibly have simplified things a bit. On the other hand, what I’ve got works and was probably
    a bit simpler to implement. On the other hand, it means changing FitNesse :(
  • I’ve currently implemented the new interface in the fitnesse.wiki namespace, and I build it within the same
    Eclipse project as the rest of the FitNesse code. It should really be in its own separate jar file, but that seemed overkill for what I was doing at the moment (especially as it’s only one source file).
  • I’ve only done manual testing on this. I don’t know enough about either FitNesse or JavaSVN to sanely test what I’ve done.
    I’m sure it’s possible, and I hope that if others find this hack useful, they could help me to test it properly. I’m somewhat ashamed of this situation, given my firm belief in TDD – it’s due to a lack of understanding of where to go, not a belief that I’ll have magically got the code right. On the plus side, all the built-in FitNesse tests still pass, so I’m reasonably confident that if you run it without actually using the Subversion code, it’ll still work.
  • I’m really worried about threading. It’s unlikely to be a problem unless you happen to get two users doing things to the same pages at the same time, but the level of locking present in FileSystemPage doesn’t really cut it. That level is too low to be particularly useful, as one responder may need to change several pages on disk, and that should be done reasonably atomically. (I don’t even try to do it in an atomic way in terms of Subversion, but stopping other disk activity from interfering would be helpful.) Of course, you should never end up with a hosed Subversion repository (I really hope the server just wouldn’t let you do that) but it may be possible to get into a situation where you need to either do some delicate work updating the working copy manually, or just check the whole tree out again.
  • Currently, files (the ones under the files directory) aren’t versioned. I’m not sure how easy that will be to fix, but it’s
    obviously something which is needed before it’s really production-ready. Hooks are needed for upload, delete and rename. Creating a directory probably doesn’t need to be versioned, so long as the directory is put under version control when the first file is created.

The whole change (a total of seven files – it’s a relatively small code change, all things considered) is available along with installation instructions on my main web site. It’s pretty basic at the moment, but if it all takes off, who knows what could happen?

List.ForEach vs foreach(…)

A thread came up yesterday on the C# newsgroup about when to use the “normal” foreach
and when to use List<T>.ForEach (assuming, of course, that one is dealing with a
List<T> in the first place). Obviously there are readability issues, but we ended up focusing
on performance. (Isn’t that telling in its own right? How often is the iteration part rather than
the body going to dominate and be a significant bottleneck? Anyway, I digress.)

So, I wrote a small benchmark, and Patrick asked me to blog about it. I’ve refactored the test I posted on the newsgroup and added a couple more tests as suggested by Willy Denoyette. The source code is a little bit unwieldy (and frankly tedious) to include in this blog post – download it if you’re interested.

The test basically creates a list of strings, each being “x”. Each test case iterates through the
list a fixed number of times, keeping a running total of the lengths of strings it sees. The result
is checked and the time taken is reported. This is what the individual tests do:

  • LanguageForEach just uses foreach (string x in list) in the obvious way.
  • NewDelegateEachTime uses an anonymous method as the parameter to List.ForEach<T>, where that method captures a different variable each “outer” iteration. That means a new delegate has to be created each time.
  • CachedDelegate creates a single delegate and uses that for all calls to List<T>.ForEach.
  • LanguageForEachWithCopy1 copies the list to an array each “outer” iteration, and then uses foreach over that array.
  • LanguageForEachWithCopy2 copies the list to an array once at the start of the test, and then uses foreach over that array.

Here are the results, with a few different test cases (all doing the same amount of work overall). I shall attempt to tabulate them a bit better when I get some time :)

Test parameters: Size=10000000; Iterations=100
Test 00:00:11.8251914: LanguageForEach
Test 00:00:05.3463387: NewDelegateEachTime
Test 00:00:05.3238162: CachedDelegate
Test 00:00:22.1342570: LanguageForEachWithCopy1
Test 00:00:03.7493164: LanguageForEachWithCopy2

Test parameters: Size=1000000; Iterations=1000
Test 00:00:11.8163135: LanguageForEach
Test 00:00:05.3392333: NewDelegateEachTime
Test 00:00:05.3334596: CachedDelegate
Test 00:00:26.9471681: LanguageForEachWithCopy1
Test 00:00:03.5251209: LanguageForEachWithCopy2

Test parameters: Size=100000; Iterations=10000
Test 00:00:11.6576344: LanguageForEach
Test 00:00:05.2225531: NewDelegateEachTime
Test 00:00:05.2066938: CachedDelegate
Test 00:00:16.2563401: LanguageForEachWithCopy1
Test 00:00:03.0949064: LanguageForEachWithCopy2

Test parameters: Size=100; Iterations=10000000
Test 00:00:12.2547105: LanguageForEach
Test 00:00:04.9791093: NewDelegateEachTime
Test 00:00:04.6191521: CachedDelegate
Test 00:00:06.0731525: LanguageForEachWithCopy1
Test 00:00:02.8182444: LanguageForEachWithCopy2

The LanguageForEachWithCopy1 results surprised me, as I’d really expected the
performance to go up as the number of iterations went up. It seems it’s cheaper to copy
a short list many times than a long list a few times…

Singletons and inheritance

For a long time, when people have asked about having inheritance and singletons, I’ve stated flatly that a singleton can’t be derived from. It stops being a singleton at that point. Even if the class is internal and you can prove that no other classes in the assembly do derive from the singleton and break the pattern’s effect, it’s still not a genuine singleton.

It was only when I was thinking about one of the comments about my enhanced enums proposal that I realised there’s an alternative approach. You can derive from a singleton as nested types of the Singleton itself and still keep the private constructor. That means that the singleton nature is still contained within the body of the text which declares the singleton class, even though that text actually declares more classes. Indeed, the singleton itself can even be abstract. Here’s an example:

using System;

public abstract class DataProvider
{
    static DataProvider instance = CreateDataProvider();
    
    public static DataProvider Instance
    {
        get { return instance; }
    }
    
    // Note that nested classes can call private members
    private DataProvider() {}

    public abstract void Connect();
    
    static DataProvider CreateDataProvider()
    {
        // Use Oracle on a Sunday, SQL Server otherwise
        if (DateTime.Now.DayOfWeek==DayOfWeek.Sunday)
        {
            return new OracleProvider();
        }
        else
        {
            return new SqlServerProvider();
        }
    }
    
    // Note that there’s no need to make the constructors
    // for the nested types non-public, as the classes
    // themselves are private to DataProvider.
    
    class OracleProvider : DataProvider
    {
        public override void Connect()
        {
            Console.WriteLine (“Connecting to Oracle”);
        }
    }

    class SqlServerProvider : DataProvider
    {
        public override void Connect()
        {
            Console.WriteLine (“Connecting to SQL Server”);
        }
    }
}

I’m not suggesting you should actually use a singleton for a data provider like this –
it just seemed like a simple example to demonstrate the point.

It is easy to validate that the singleton only allows one instance of DataProvider
to ever be constructed. (This version isn’t fully lazy, but that could be added if desired.)

It looks like I’ll have to revise my statement about inheritance from now on…

ICloneable? Not quite…

I don’t usually post personal news on my blog, but this is fairly major. Some of you may know that my wife, Holly, is pregnant. What you won’t know – and what we didn’t know until today – was that we’re having twins. Eek! A lovely surprise, if somewhat scary. For those of you who like piccies, the scans are on my web site…

Now if you’ll excuse me, I think I’ll go and lie down. And to think I was going to write up C# 2.0 features tonight…

Nice doc comment idea

I’ve just been reading the
transcript of a whiteboard session with Anders Hejlsberg
and one of the questions
is really, really good:

Question: My problem is I’ve got these XML doc comments
that are duplicated. I just strip off one. I guess it would be a neat
language feature to be able to somehow indicate this is my primary- my
big method, right? With all the parameters. Then the other ones are
just going to borrow that XML doc comment.

Hejlsberg: Yes, okay. Now that I think is- that’s not a bad idea.
That yes, they should be able to share the documentation. I can sympathize
with that.

That’s not just “not a bad idea”. That’s a fantastic idea. When I was
writing the BitConverter and BinaryReader etc equivalents
in my miscellaneous utility library
the doc comments for the overloads took significantly longer to write than the actual code.
(Most of the code was just each overload calling a “master” routine.) Now, sometimes
that comment won’t be exactly the same for each overload; sometimes there’ll effectively
be placeholders: “Converts the specified ${type} value into ${n} bytes” or whatever. I don’t
know exactly how this could be done elegantly (and I’m not actually suggesting the ${token} syntax!), but it’s something that should be strongly
considered for a later version of C#. It could make life a lot simpler in some cases.

Enhanced enums in C#

This will be an evolving post, hopefully. (If no-one comments on it, it probably
won’t change unless I come up with better ideas myself.) Since working on a Java
project last year, I’ve been increasingly fed up with C#’s enums. They’re really
not very object oriented: they’re not type-safe (you can cast from one enum to
another via a cast to their common underlying type), they don’t allow any
behaviour to be specified, etc. They’re just named constant integral values.
Until I played with Java
1.5’s enum support
, that wouldn’t have struck me as being
a problem, but (at least in some cases) enums can give you so much more. This post
is a feature proposal for C# 4.0. (I suspect the lid for this kind of thing is closed
on 3.0.)

What’s the basic idea?

Instead of being a fixed set of integral values, imagine if enums were a fixed set of
objects. They could have behaviour (and state of sorts), just like other objects – the
only difference would be that there’d only ever be one instance for each value. When
I say they could have “state of sorts” I mean that two values of an enum could differ
in just what they represented. For instance, imagine an enumeration of coins – I’ll use
US coins for convenience for most readers. Each value in the enum would have a name
(Cent, Nickel, Dime, Quarter, Dollar) and a monetary value in cents (1, 5, 10, 25, 100
respectively). Each might have a colour property too, or the metal they’re made of. That’s
the kind of state I mean. In fact, there’s nothing in the proposal below to say that the
state within an enum has to stay the same. I’d recommend that it did stay the same,
but maybe someone’s got an interesting use case where mutable enums would be useful.
(Actually, it’s not terribly hard to think of an example where the underlying state mutates
even if it doesn’t appear to from a public property point of view – some properties could
be lazily initialised if they might take time to compute.)

As well as properties, the enum type could have methods, just as other types do. For instance,
an enumeration of available encryption types may have methods to encrypt data. (I’m giving
fairly general examples here – in my experience, the actual enums you might use tend to be
very domain-specific, and as such don’t make good examples. I’m also trying to steer well
clear of risking giving away any intellectual property owned by my employer.)

Now, consider the possibilities available when you bring polymorphism into the picture. Not
every implementation of a method has to be the same. Some enum values may be instances of
a type derived from the top-most one. This would be limited at compile-time to make enums
fixed – you couldn’t derive from an enum type in the normal way, so you’d
always know that if you had a reference to an instance of the enum type, you’d got one of
the values specified by the enum.

What’s the syntax?

I propose a syntax which for the simplest of cases looks very much like normal enumerations,
just with class enum instead of enum:

public class enum Example
{
    FirstValue,
    SecondValue;
}

Note the semi-colon at the end of the list of values. This could perhaps be optional,
but when using the power of “class enums” (as I’ll call them for now) in a non-trivial way,
you’d need them anyway to tell the compiler you’d reached the end of the list of values,
and other type members were on the way. The next step is to introduce a constructor and
a property:

public class enum Coins
{
    Cent(1),
    Nickel(5),
    Dime(10),
    Quarter(25),
    Dollar(100);
    
    // Instance variable representing the monetary value
    readonly int valueInCents;
    
    // Constructor - all enum constructors are private
    // or protected
    Coins(int valueInCents)
    {
        this.valueInCents = valueInCents;
    }
    
    public int ValueInCents
    {
        get { return valueInCents; }
    }
}

Now, there would actually be some significant compiler magic going on at this point. Each of
the generated constructor calls would actually have an extra parameter – the name of the value. That
parameter would be present in every generated constructor, and if no constructors were declared, a protected
constructor would be generated which took just that parameter. Each constructor would implicitly
call the base constructor which would stash the name away and make it available through a Name
property (and no doubt through calls to ToString() too). What’s the base class in this case?
System.ClassEnum or some such. This could be an ordinary type as far as the CLR is concerned,
although language compilers would be as well to prevent direct derivation from it. This leaves room for
some compilers to allow types which aren’t really enums to derive from it, but does have the advantage
of not requiring a CLR change. Whenever you use someone else’s code you’re always taking a certain amount on
trust anyway, so arguably it’s not an awful risk. More about the services of System.ClassEnum
later…

The next piece of functionality is to have some members with overridden behaviour. The canonical example
of this is simple arithmetic operations – addition, subtraction, division and multiplication. The enumeration
contains a value for each operation, and has an Eval method to perform the operation. Here’s
what it would look like in C#:

public class enum ArithmeticOperation
{
    Addition
    {
        public override int Eval(int x, int y)
        {
            return x+y;
        }
    },
    
    Subtraction
    {
        public override int Eval(int x, int y)
        {
            return x-y;
        }
    },
    
    Multiplication
    {
        public override int Eval(int x, int y)
        {
            return x*y;
        }
    },
    
    Division
    {
        public override int Eval(int x, int y)
        {
            return x/y;
        }
    };
    
    public abstract int Eval(int x, int y);
}

Sometimes, you may wish to save a bit of space and specify the implementation of
a method as a delegate – especially if the method would otherwise be abstract (i.e.
there was no “common” implementation which most values would use). Here, C#’s
anonymous method syntax helps:

public class enum ArithmeticOperation
{    
    delegate int Int32Operation (int x, int y);
    
    Addition (delegate (int x, int y) { return x+y; }),
    Subtraction (delegate (int x, int y) { return x-y; }),
    Multiplication (delegate (int x, int y) { return x*y; }),
    Division (delegate (int x, int y) { return x/y; });
        
    Int32Operation op;
    
    ArithmeticOperation (Int32Operation op)
    {
        this.op = op;
    }
    
    public int Eval (int x, int y)
    {
        return op(x, y);
    }
}

That’s still a bit clumsy, of course – let’s try with lambda function syntax instead:

public class enum ArithmeticOperation
{    
    Addition ( (x,y) => x+y),
    Subtraction ( (x,y) => x-y),
    Multiplication ( (x,y) => x*y),
    Division ( (x,y) => x/y);
        
    Func<int, int> op;
    
    ArithmeticOperation (Func<int,int> op)
    {
        this.op = op;
    }
    
    public int Eval (int x, int y)
    {
        return op(x, y);
    }
}

Now we’re really cooking! Of course, some of the time you’ll be able to provide a single implementation for most values,
which only some values will want to override. Something like:

public class enum InputType
{
    Integer,
    String,
    Date
    {
        // Default implementation isn't quite good enough for us
        public override string Format(object o)
        {
            return ((DateTime)o).ToString("yyyyMMdd");
        }
    };
    
    // Default implementation of formatting
    public virtual string Format(object o)
    {
        return o.ToString();
    }
}

So far, this is all quite similar to Java’s enums in appearance. Java’s enums also come with an ordinal
(the position of declaration within the enum) automatically, but in my experience this is as much of a
pain as it is a blessing. In particular, as that ordinal can’t be specified in the source code, if you
have other code relying on specific values (e.g. to pass data across a web-service) you have to leave
bogus values in the list in order to keep the ordinals of the later values the same. Java also only
allows you to specify the constructors in “top-most” enum. This can occasionally be a nuisance. Let’s extend
the enum above to include DateTime and Time – both of which need the same kind of
“special” formatting. In Java, you’d have to override Format in three different places, like
this:

public class enum InputType
{
    Integer,
    String,
    DateTime
    {
        public override string Format(object o)
        {
            return ((System.DateTime)o).ToString("yyyyMMdd HH:mm:ss");
        }
    },
    Date
    {
        public override string Format(object o)
        {
            return ((System.DateTime)o).ToString("yyyyMMdd");
        }
    },
    Time
    {
        public override string Format(object o)
        {
            return ((System.DateTime)o).ToString("HH:mm:ss");
        }
    };
    
    public virtual string Format(object o)
    {
        return o.ToString();
    }
}

I would propose that enum values could reuse each other’s implementations, possibly
parameterising them via constructors. The above could be rewritten as:

public class enum InputType
{
    Integer,
    String,
    DateTime("yyyyMMdd HH:mm:ss")
    {
        string formatSpecifier;
        
        protected DateTime(string formatSpecifier)
        {
            this.formatSpecifier = formatSpecifier;
        }
        
        public override string Format(object o)
        {
            return ((System.DateTime)o).ToString(formatSpecifier);
        }
    },
    Date : DateTime("yyyyMMdd"),
    Time : DateTime("HH:mm:ss");
    
    public virtual string Format(object o)
    {
        return o.ToString();
    }
}

If Date wanted to further specialise the class (e.g. if another method needed overriding),
it could add implementation there too. Note that the DateTime constructor does not explicitly
call any constructor. In this case, an implicit call to the InputType constructor which took
only the name parameter would be made. Explicit calls to base class constructors could be included in the normal
way – the extra parameter would be entirely hidden from the source code. Only protected constructors could
be called by derived types in the normal way.

Switch

Switch statements would appear in exactly the same way they do now. (Possibly without the qualification (e.g.
case Time: instead of case InputType.Time:. The code is more readable without the
qualification, and is unambiguous, but it would be inconsistent with the current handling of switch cases
for “normal” enums.) The implementation would work a lot like strings – either using the equivalent of
a sequence of if statements or building a map behind the scenes. This is where keeping something
like Java’s ordinals would speed things up, but then I would at least want something like an attribute to be able to
specify the value in source code to avoid the problems described in Java earlier. Note that only reference
equality needs to be checked in any of these cases, as only one instance of any value would be created.

Static field initializers and static constructors

Java has restrictions on where you can use static fields in enums, because the static field initializers
are executed after the enum values have been created. Static fields are useful in a surprising number
of circumstances, mostly getting at an enum value dynamically by something other than name. The rules
for this would need to be considered carefully – sometimes it’s useful to have code which will be run
after the enums have all been set up; other times you want it beforehand (so you can use the static fields
during initialization, e.g. to add a value to a map).

Other features

Like Java, there could be an EnumSet<T> type which would be the equivalent of using
FlagsAttribute on normal enums. Indeed, the compiler could even generate operator overloads
to make this look nicer.

In Java, some enums with many values overriding many methods can end up being pretty large. In
C#, of course, we can use partial types to split the whole enum definition over several
files. (Some may object to this, others not – it would be available if you wanted it.)

Open questions

  • The potential abuse problem mentioned earlier
  • Serialization/deserialization would need to know to use the previously set up values
  • Should identifying values (like Java ordinals) be present, if only for switch performance?

I suspect there are other things I haven’t thought of, but with any luck this will be food for thought.

Deadlock detection – finally released

I’d hoped to be able to make this post a week ago, but adding extra unit tests, performance tests and documentation took longer than expected. (Doesn’t it always?)

I’ve now refactored the previous incarnation of SyncLock in my Miscellaneous Utility Library (snappy title, huh?) and added a new type of lock which can detect deadlocks (throwing an exception instead of entering the deadlock-prone state). There’s also a usage page explaining how to use the locks, and what the performance impact is. (Well, what it is on my box, anyway.) Any further suggestions now it’s concrete are welcome, of course.

Pedantry – how much is too much?

I’m a pedant, there’s no doubt about it. I’m particularly pedantic when it comes to terminology in computing discussions – at least where I see value in being precise about what is meant. So, when discussing static constructors in a mailing list thread recently, I’ve been very carefully distinguishing between a static constructor (which is a C# term) and a type initializer (which is a CLI term). This hasn’t been met terribly favourably by those who wish to use the term “static constructor” to mean both the .cctor member in a (compiled) type and the C# static constructor, despite them being slightly different in semantics and belonging to different domains. Now, I don’t wish to spill that discussion over onto my blog, but it has made me think about the general issue of pedantry when it comes to terminology.

Pedantry is rarely popular, but I believe it does bring value to a discussion, especially when some subtleties are involved. I generally assume a specification to be the authoritative source of information on terms related to the topic covered by the specification, as it’s a piece of common ground on which to base discussions. (The exception to this is if the spec is generally agreed to be incorrect in a particular regard.) If I talk about something being a variable and you understand “variable” in a completely different way to me, it’s a potential source of great confusion. I’m not pedantic to gain a feeling of superiority – I’m pedantic to try to make sure everyone’s effectively speaking the same language.

Of course, you don’t need to be absolutely precise all the time. If I were discussing an ASP.NET problem, for instance, I probably wouldn’t feel too bad about a sentence such as “x is now a string of length 5”. However, if I were discussing variables, reference types etc, I’d probably try to be more precise: “The value of x is now a reference to a string of length 5.” Writing (or reading) the second style for prolonged periods gets quite tedious, but I believe it’s important to be able to move into that mode when the need arises.

So, the question is: am I the only one who feels this way? I would expect most of the readers of this blog to be people who’ve read either my newsgroup posts, mailing list posts, or C# articles, so you probably have a fair idea of what I’m like. Do I go over the top, or do you find it useful? Is there a way of bringing precision to a discussion without irritating people (as I tend to, unfortunately)? Just to possibly remind you of things I’m often pedantic about, here’s a brief list of “pet peeves” which tend to involve people cutting fast and loose with terminology:

  • Value types “always being on the stack”
  • “Objects are passed by reference by default”
  • “C# supports two floating-point types: float and double.” (That one’s in the C# spec, unfortunately – decimal is also a floating point type.)
  • “I’m having trouble with ASCII characters above 127…” (along with its side-kick “I’m using extended ASCII”)
  • Volatility and atomicity being mixed up