Functional Inspiration – A simple Option type

In F#, the option type is a built-in Discriminated Union type which allows to handle nicely the fact that an expression can represent some value or none. In C#, we have almost this construct when we use the Nullable<T>, but as I’ve already stated before, this type is available only for value types. Here is an option type that deals also with reference types.

I’ve already played with an Irreleventable<T> type in the past, and the implementation of it is quite the same as what I’ll do today, but the semantics are different, and I don’t want to re-use this type in a misleading way.

So today, I bring you “yet another option type” in C# :

public struct Option<T>
{
    private readonly bool isSome;
    public bool IsSome
    {
        get
        {
            return isSome;
        }
    }

    private readonly T value;
    public T Value
    {
        get
        {
            if (!isSome) throw new NotSupportedException();
            return value;
        }
    }

    private Option(bool isSome, T value)
    {
        this.isSome = isSome;
        this.value = value;
    }

    public static Option<T> Some(T value)
    {
        return new Option<T>(true, value);
    }

    public static Option<T> None()
    {
        return new Option<T>(false, default(T));
    }

    public override int GetHashCode()
    {
        return isSome
            ? value.GetHashCode()
            : -1;
    }

    public override bool Equals(object other)
    {
        if (!(other is Option<T>))
            return false;

        Option<T> otherOption = (Option<T>)other;

        return IsSome
            ? (value == null && otherOption.Value == null)
                || value.Equals(otherOption.Value)
            : !otherOption.IsSome;
    }

    public override string ToString()
    {
        return this.IsSome
            ? this.value.ToString()
            : String.Empty;
    }
}

The only noticeable differences with the Irreleventable type are the (chosen) lack of conversion operators, and the equality comparison, as an Option<T> will never be considered equal to an instance of T (unlike the Irreleventable).

Why would I write a blog post simply to introduce this type, without any context ? More to come soon.

Posted in Functional Inspiration | Tagged , | Comments Off

Elitism ? Or just raising the bar ?

Last Thursday, I’ve attended an open forum organised by ALT.NET France user group, about the Software Craftsmanship Community and the “Fier d’être développeur” (“Proud to be dev”) groups, in order to compare their intents and try to explain why they exist and what they try to achieve.

One of the questions that was raised during the evening was the following : Is the “Software Craftsmanship” movement elitist or is it a way to democratize good practices ? After a great deal of discussion, we agreed on the fact that it can be seen the both ways. Let’s face it : we meet in the evening to talk about programming… We’re part of the “10 percent alpha-geeks”. And yes, there is some kind of elitism about it.

On one hand, to someone that comes for the first time, all the practices, languages and tools we talk about might seem too complex, and frighten him (or her). On the other hand, realizing that there are so many things that we don’t know is the first step to getting better, isn’t it ? To my mind, this whole question of “raising the bar” instead of letting the average level go low, is not specific to programming but is true for any kind of teaching/learning topic. What makes it so important in programming is that we can’t stop learning during our career, if we want to stay up-to-date…

But if our goal is to “raise the bar”, how do we do it on a day-to-day basis ? If we want to show our colleagues some tricks, so that they ask for more, not that they run away…

Let’s illustrate that with an example from real life. A couple days ago I wanted extract from several data series the dates that were common to all these series. This might seem quite simple, but there are numerous ways to do that, and I find it a good case study of how to balance readability and (perceived) complexity…

<YAK-SHAVING>My Visual Studio 2012 RC has expired… I’m switching to MonoDevelop in order to write my sample code…</YAK-SHAVING>

Let’s consider several collections of points, where a point is simply a date and a decimal value :

public class Point
{
    public DateTime Date { get; set; }
    public decimal Value { get; set; }
}

And now imagine that I have a collection of series of points, represented as such :

IEnumerable<IEnumerable<Point>> series

Now the point is to get the dates that are common to all these series. With a straight implementation, this could go this way :

[Test()]
public void TestStraightLoops()
{
    IEnumerable<IEnumerable<Point>> series =
        DataSeries.GetSeries(2013);

    List<DateTime> commonDates = new List<DateTime> ();
    bool first = true;
    foreach (var serie in series)
    {
        if(first)
        {
            foreach(var point in serie)
            {
                commonDates.Add(point.Date);
            }
        }
        else
        {
            List<DateTime> datesToRemove = new List<DateTime>();
            foreach(var commonDate in commonDates)
            {
                bool found = false;
                foreach(var point in serie)
                {
                    if(commonDate == point.Date)
                    {
                        found = true;
                        break;
                    }
                }

                if(!found)
                {
                    datesToRemove.Add(commonDate);
                }
            }

            foreach(var dateToRemove in datesToRemove)
            {
                commonDates.Remove(dateToRemove);
            }
        }
        first = false;
    }

    Assert.AreEqual(76, commonDates.Count);
}

OK, this works. How long does it take to read it and understand it ? What if, instead, I chose to use my basic knowledge of LINQ ? I’ll skip a few steps, but what if came up with this :

[Test()]
public void TestForEachIntersect ()
{
    IEnumerable<IEnumerable<Point>> series =
        DataSeries.GetSeries(2013);

    IEnumerable<DateTime> commonDates = null;

    foreach (var serie in series)
    {
        var dates = serie.Select(p => p.Date);

        commonDates = (commonDates == null)
            ? dates
            : commonDates.Intersect(dates);
    }

    Assert.AreEqual(76, commonDates.Count());
}

This is obviously shorter. Is it more or less difficult to read and maintain ? Should I stop here ? What if wrote the following, using Aggregate to do the same thing as above, but inside an extension method ?

public static IEnumerable<TResult> IntersectMany<T, TResult>
    (this IEnumerable<IEnumerable<T>> source,
     Func<T, TResult> selector)
{
    return source.Aggregate(
        (IEnumerable<TResult>)null,
        (a, s) => a == null
                ? s.Select(selector)
                : a.Intersect(s.Select(selector)));

}

Obviously this method is less readable… But the consumer code is now the following :

[Test()]
public void TestIntersectMany()
{
    IEnumerable<IEnumerable<Point>> series =
        DataSeries.GetSeries(2013);
    
    var commonDates = series
        .IntersectMany(p => p.Date);
    
    Assert.AreEqual(76, commonDates.Count());
}

And… I kind of like the expressiveness of it. So where must we stop ? To my mind, we must stop when it can be maintained. Aren’t we pragmatic programmers, after all ?

I think that Software Craftsmanship is very well summed-up in Sandro Mancuso’s book title : “Software Craftsmanship : Professionalism, Pragmatism, Pride”. Those words are in the right order. Pride is part of it, but it come only third.

Posted in Practices | Tagged , , | Comments Off

RPSLS — Rock Paper Scissors Lizard Spock

Let’s start with a tweet from earlier today :

If you follow the link, you’ll get to a Google Play application that allows you to play the (in-)famous RPSLS (Rock-paper-scissors-lizard-Spock) game. Why that tweet stroke me is that I had already played (with code !) around that game a few months ago…

Although this is just a variant of the classical rock-paper-scissors game, the two additional gestures shift the number of gesture combinations to 25, as shown on this matrix:

(image taken from http://en.wikipedia.org/wiki/File:Normal_form_matrix_of_Rock-paper-scissors-lizard-Spock.jpg)

There could be several ways to test these different combinations, for instance using the previous matrix as a reference, but… come on…. a closed set of values, and a simple behaviour… That’s just a perfect candidate for an enum ! And the best part is that I have actually implemented this as a test two months ago (proof on Github !).

Let’s first define the possible game outcomes :

public class GameOutcome : PolymorphicEnum<GameOutcome>
{
    public static GameOutcome WIN = Register();
    public static GameOutcome LOSE = Register();
    public static GameOutcome DRAW = Register();
}

Then we define the Gesture class and its values :

public class GeekGesture : PolymorphicEnum<GeekGesture>
{
    public static GeekGesture ROCK = Register();
    public static GeekGesture PAPER = Register();
    public static GeekGesture SCISSORS = Register();
    public static GeekGesture SPOCK = Register();
    public static GeekGesture LIZARD = Register();
    [...]

The trick here is that I changed the order of the values int the enum from Rock – paper – scissors – lizard – Spock to Rock – paper – scissors – Spock – lizard. This way, each values beats its predecessor and its second successor, and loses against its successor and second predecessor…

The behaviour can then be simply implemented based on the integer values of the enums :

// we can use the int representation and a modulo trick !
public GameOutcome PlayAgainst(GeekGesture other)
{
    return this == other
        ? GameOutcome.DRAW
        : (GameOutcome)(((other + 5 - this) % 5) % 2);
}

Now we can write the tests in a very expressive way :

[TestMethod]
public void gesture_against_2nd_next_is_a_win()
{
    Assert.AreEqual(GameOutcome.WIN,
        GeekGesture.ROCK.PlayAgainst(GeekGesture.SCISSORS));
    Assert.AreEqual(GameOutcome.WIN,
        GeekGesture.PAPER.PlayAgainst(GeekGesture.SPOCK));
    Assert.AreEqual(GameOutcome.WIN,
        GeekGesture.SCISSORS.PlayAgainst(GeekGesture.LIZARD));
    Assert.AreEqual(GameOutcome.WIN,
        GeekGesture.SPOCK.PlayAgainst(GeekGesture.ROCK));
    Assert.AreEqual(GameOutcome.WIN,
        GeekGesture.LIZARD.PlayAgainst(GeekGesture.PAPER));
}

So… here is my answer to Leonard :

Posted in Uncategorized | Comments Off

Cartesian products in LINQ (fluent syntax)

Have you ever tried to combines sequences in order to build Cartesian products in LINQ ? This is really easily achieved using the query expressions syntax, writing for instance :

var ints = Enumerable.Range(1, 4);
var longs = Enumerable.Range(1, 3).Select(i => (long)i);

var products = from i in ints
    from l in longs
    select i * l;

When I write LINQ queries, I tend to use more often the fluent syntax, as it is more powerful, and allows me to use a wider range of operators. I also try not to mix both syntaxes, because I find it quite confusing. When I want to perform, inside of a more complex query, a simple cross-product as the previous one, the “fluent” equivalent syntax is the following :

var products = ints.SelectMany(i => longs.Select(l => i * l));

In fact, this syntax works very well, but I don’t find it as expressive as the first one. And if you go one step further and add a third sequence to the party…

var ints = Enumerable.Range(1, 4);
var longs = Enumerable.Range(1, 3).Select(i => (long)i);
var strings = new[] { "a", "b", "c" };

var classic = from i in ints
    from l in longs
    from s in strings
    select (i * l).ToString() + s;

The “fluent” syntax gets even more confusing (at least to me) :

var fluent = ints.SelectMany(
    i => longs.SelectMany(
    l => strings.Select(s => (i * l).ToString() + s)));

I think that what bothers me might be the ever-increasing number of unclosed parenthesis… Anyway, as usual, I played with extensions methods and here is what I came up with, using a new “Cross” method, for the 2 sequences cross-product :

var results = ints
    .Cross(longs)
    .Select((i, l) => i * l);

And the same syntax for the 3 sequences cross product :

var results = ints
    .Cross(longs)
    .Cross(strings)
    .Select((i, l, s) => (i * l).ToString() + s);

Don’t you find it more expressive ?

Finally, here are the extensions methods implementations :

public static IEnumerable<Tuple<TLeft, TRight>> Cross<TLeft, TRight>(
    this IEnumerable<TLeft> left, IEnumerable<TRight> right)
{
    return left.SelectMany(l => right.Select(r => Tuple.Create(l, r)));
}

public static IEnumerable<Tuple<TLeft1, TLeft2, TRight>> Cross<TLeft1, TLeft2, TRight>(
    this IEnumerable<Tuple<TLeft1, TLeft2>> left, IEnumerable<TRight> right)
{
    return left.SelectMany(l => right.Select(r => Tuple.Create(l.Item1, l.Item2, r)));
}

public static IEnumerable<TResult> Select<T1, T2, TResult>(
    this IEnumerable<Tuple<T1, T2>> source, Func<T1, T2, TResult> selector)
{
    return source.Select(t => selector(t.Item1, t.Item2));
}

public static IEnumerable<TResult> Select<T1, T2, T3, TResult>(
    this IEnumerable<Tuple<T1, T2, T3>> source, Func<T1, T2, T3, TResult> selector)
{
    return source.Select(t => selector(t.Item1, t.Item2, t.Item3));
}

I must admit that those generic methods signatures are horrible, though…

Posted in LINQ | Tagged , , | Comments Off

Polymorphic enums in C#, implementation revealed

How can we implement a polymorphic enum to mimic the Java ones ?

In a previous post, as an answer to @cyriux’s one, I showed how we could try to use a polymorphic enum in C# in order to mimic the Java ones. I have ported to C# the Java samples, using a base class called PolymorphicEnum. In this post, I’m going to give details about the implementation of this class.

The very first objectives are :

  1. To create an enum that derives from a base PolymorphicEnum.
  2. This derived enum must be able to define a set of values.

Getting started

What I want to be able to write is something like :

public class SomeEnum : PolymorphicEnum
{
    public static SomeEnum FirstValue;
    public static SomeEnum SecondValue;
}

As I can’t change the compiler behaviour, the two values declared in the previous sample must be instantiated somehow. The declaration then becomes :

public class SomeEnum : PolymorphicEnum
{
    public static SomeEnum FirstValue = Register();
    public static SomeEnum SecondValue = Register();
}

In order to be able to write such code, here is what I can do :

  1. First, the class I want to define is only meant to be derived from, so it must be abstract. Therefore, it can only be a class, and not a struct. So I’ll have to override the Equals and GetHashCode methods in order to get a value comparison behaviour for two different instances of enums. But if the singleton-ness is implemented properly… I should never have two instances !
  2. The class will have a generic Ordinal read-only property, where T is a value type. If not provided, this type will be an int by default.
  3. In order to instantiate enum values, the base class will have to expose a static protected method “Register”.

This leads us to this basic definition :

public abstract class PolymorphicEnum<T>
    where T : struct, IComparable<T>, IConvertible
{
    public T Ordinal { get; private set; }
    public string Name { get; private set; }

    protected PolymorphicEnum()
    {
    }

    public override string ToString()
    {
        return this.Name;
    }
}

And in order to get an int as the default underlying type, we define a derived class :

public abstract class PolymorphicEnum : PolymorphicEnum<int>
{
}

Adding registration

Ok, this has been quite simple. Now, we want the base class to allow its children to register instances. This means the base class will be responsible for instantiating, registering and tracking these instances. In order for the base class to instantiate the derived classes, we need to know their type in the method. To to this, we introduce a generic type parameter. We also want this method to accept an optional “ordinal” parameter, to handle the case where the ordinal values are defined by user-code. What we need is a method of the form :

protected static TEnumInstance Register<TEnumInstance>(
    Nullable<T> ordinal = null)
where TEnumInstance : new()

Notice the “new()” generic constraint on the type parameter : the given type has to have a parameter-less constructor, which we’ll use to instantiate it. But as we go towards the polymorphic behaviour, the enum class that we’ll have to instantiate can be a sub-class from the actual enum type ! For instance, if we take the first sample from the previous post, we have the following inheritance :

Because we do not want to give both of these type arguments on each Register call, the TEnum type argument moves up to the class level, and the class definition and Register method signature shift the following way:

public abstract class PolymorphicEnum<T>
    where T : struct, IComparable<T>, IConvertible  
=>
public abstract class PolymorphicEnum<T, TEnum>
where T : struct, IComparable<T>, IConvertible
where TEnum : PolymorphicEnum<T, TEnum>, new()
protected static TEnumInstance Register<TEnumInstance>(
    Nullable<T> ordinal = null)
where TEnumInstance : new()
=>
protected static TEnum Register<TEnumInstance>(
    Nullable<T> ordinal = null)
where TEnumInstance : TEnum, new()

The registration of the enum values is performed in a static dictionary, so here is at last the register method :

protected static TEnum Register<TEnumInstance>(
        Nullable<T> ordinal = null)
    where TEnumInstance : TEnum, new()
{
    if (!ordinal.HasValue)
    {
        ordinal = registeredInstances.Any()
            ? registeredInstances.Keys.Max().PlusOne()
            : default(T);
    }

    TEnum instance = new TEnumInstance();
    instance.Ordinal = ordinal.Value;

    registeredInstances.Add(ordinal.Value, instance);

    return instance;
}

Comment : how to implement a “PlusOne” extension method, that could increment any of the underlying types supported by an enum, has been a puzzle of its own… See this post for my solution !

Simplifying registration

From now on we can register enum value the following way :

public class SomeEnum : PolymorphicEnum<SomeEnum>
{
    public static SomeEnum FirstValue = Register<SomeEnum>();
    public static SomeEnum SecondValue = Register<SomeEnum>();
}

Wait !? Why must we provide the type to the Register method, if that is the same as the generic argument of the class ? Let’s move forward and define an additional Register method :

protected static TEnum Register(Nullable<T> ordinal = null)
{
    return Register<TEnum>(ordinal);
}

And the registration gets simpler again :

public class SomeEnum : PolymorphicEnum<SomeEnum>
{
    public static SomeEnum FirstValue = Register();
    public static SomeEnum SecondValue = Register();
}

Finding the names

So now we can register enum values, optionally specifying the ordinal value… but we’re not done yet ! I mean, aren’t we supposed to be able to convert enums from and to strings ? From the previous steps, we have a Name property with a private setter, and an overridden ToString() method. But the Name property is never set ! In my first implementations, providing the Register method with the string to associate with the value was mandatory. I was not satisfied with this solution, and I came up with the following replacement solution :

  1. I added a static field to the class :
    private static bool namesInitialized = false;
  2. I replaced the Name property implementation with this new one :
    private string name = null;
    private string Name
    {
        get
        {
            EnsureNamesInitialized();
            return this.name;
        }
        set
        {
            this.name = value;
        }
    }
  3. I implemented the EnsureNamesInitialized method :
    protected void EnsureNamesInitialized()
    {
        if (!namesInitialized)
        {
            MemberInfo[] enumMembers = typeof(TEnum).GetMembers(
                    BindingFlags.Public
                    | BindingFlags.Static
                    | BindingFlags.GetField);
    
            foreach (FieldInfo enumMember in enumMembers)
            {
                TEnum enumValue =
                    enumMember.GetValue(null) as TEnum;
    
                if (enumValue != null)
                    enumValue.Name = enumMember.Name;
            }
            namesInitialized = true;
        }
    }
  4. And finally I added this line at the end or the register method, just before the “return instance” statement :
    namesInitialized = false;

This mechanism ensures that the enum names are all computed using reflection. It assigns each enum value the name of the public static member to which it has been assigned (given the member has already been assigned and is of the correct type).

Serializing and deserializing

Nice ! We’ve made progress, really. Now we want to be able to serialize and deserialize the values from and to strings, as well as from the underlying primitive type.

Serializing to a string has been implemented from the start by the ToString() method. Deserializing will imply 4 methods signatures :

  • bool TryParse(string value, out TEnum result)
  • bool TryParse(string value, bool ignoreCase, out TEnum result)
  • TEnum Parse(string value)
  • TEnum Parse(string value, bool ignoreCase)

In the end the implementation is the following :

public static bool TryParse(string value,
                            bool ignoreCase,
                            out TEnum result)
{
    TEnum[] instances = registeredInstances
        .Values
        .Where(
            e => e.Name.Equals(
                value,
                ignoreCase
                    ? StringComparison.InvariantCultureIgnoreCase
                    : StringComparison.InvariantCulture))
        .ToArray();

    if (instances.Length == 1)
    {
        result = instances[0];
        return true;
    }
    else
    {
        result = default(TEnum);
        return false;
    }
}

The 3 other signatures simply rely on the previous method.

Concerning the other type of conversion (i.e. from and to the underlying primitive type), to stay as close as possible as how classical enums work, I have defined the following operator :

public static implicit operator T(PolymorphicEnum<T, TEnum> x)
{
    return x.Ordinal;
}

And the second one :

public static explicit operator PolymorphicEnum<T, TEnum>(T x)
{
    TEnum enumInstance;
    if (!registeredInstances.TryGetValue(x, out enumInstance))
        throw new ArgumentException(
            string.Format("Enum value {0} not found", x, "x"));

    return enumInstance;
}

Embedding data

Now we’re going to add an extra requirement : we want to embed data in the enum values. In order to store this values, I’ll be as open as I can and add an extra property typed as “object” :

protected object Data { get; private set; }

I’ll also add an extra optional parameter in the two Register methods, that become :

protected static TEnum Register(
    Nullable<T> ordinal = null,
    object data = null)
{
    return Register<TEnum>(ordinal, data);
}

and :

protected static TEnum Register<TEnumInstance>(
    Nullable<T> ordinal = null,
    object data = null)
where TEnumInstance : TEnum, new()
{
    if (!ordinal.HasValue)
    {
        ordinal = registeredInstances.Any()
            ? registeredInstances.Keys.Max().PlusOne()
            : default(T);
    }

    TEnum instance = new TEnumInstance();
    instance.Ordinal = ordinal.Value;
    instance.Data = data;

    registeredInstances.Add(ordinal.Value, instance);

    namesInitialized = false;

    return instance;
}

As you can see, not much as changed, but that is all there is to do ! A single point to mention is that nothing prevents the derived classes to change the state of the objects stored in the “Data” property. So when writing these derived classes, the developer has to be careful to enforce immutability.

Enforcing consistency

OK, I’ll soon stop this never-ending post, but there is a last detail that I wanted to explain, that is how I take care that once the set of values of an enum has been defined, it cannot be extended from any other class.

In order to register new values, you have to add new enum instances in the registeredInstances member. The way to do this is to call one of the two overloads or the Register method. If you wanted to bypass these methods, you would need to have access to the registeredInstances member, which is private in the base class, so that settles this point. But what prevents you from calling the Register methods in weird situations ? Let’s take a look at the following inheritance :

Put in code, it becomes :

public class SomeEnum : PolymorphicEnum<SomeEnum>
{
    public static SomeEnum FirstValue = Register();
    public static SomeEnum SecondValue = Register();
}

public class OtherEnum : PolymorphicEnum<SomeEnum>
{
    public static SomeEnum ThirdValueAttempt = Register();
}

public class OtherChildEnum : SomeEnum
{
    public static SomeEnum FourthValueAttempt = Register();
}

The above code is valid, and compiles without any warning. The register method is a protected method, so it can be called :

  • from any class deriving from the same base classe PolymorphicEnum<T> (with the same T type), for instance here the OtherEnum class,
  • from any sub-class, for instance here the OtherChildEnum class.

To prevent the registration of invalid values, we check at the very beginning of the Register method that the type which called the method is the same as the type being registered. To do so, we take a look at the call stack, either at the first or the second stack frame, depending on the overload of Register that was called :

StackFrame frame = new StackFrame(1);
if (frame.GetMethod().Name == "Register")
    frame = new StackFrame(2);

MethodBase enumConstructor = frame.GetMethod();
if (enumConstructor.DeclaringType != typeof(TEnum))
    throw new EnumInitializationException(
        "Enum members cannot be registered from other enums.");

This prevents the user code from registering undesired values. But there is still an edge case to be handled, pointed to me be @cyriux…

Let me show you what’s wrong… Remember the very first sample about the gestures ? Don’t look back ! Here is the code again :

/** PolymorphicEnum have behavior! **/
public class Gesture : PolymorphicEnum<Gesture>
{
    public static Gesture ROCK = Register<RockGesture>();
    public static Gesture PAPER = Register();
    public static Gesture SCISSORS = Register();

    // we can implement with the integer representation
    public virtual bool Beats(Gesture other)
    {
        return this.Ordinal - other.Ordinal == 1;
    }

    private class RockGesture : Gesture
    {
        public override bool Beats(Gesture other)
        {
            return other == SCISSORS;
        }
    }
}

The problem with this implementation is maybe not that obvious, but what if I write the following code ?

public class Godzilla : Gesture
{
    public static Godzilla Instance = new Godzilla();

    public override bool Beats(Gesture other)
    {
        return true;
    }
}

Yes, this is valid code. And the following test is green !

[TestMethod]
public void godzilla_beats_all()
{
    Assert.IsTrue(Godzilla.Instance.Beats(Gesture.ROCK));
    Assert.IsTrue(Godzilla.Instance.Beats(Gesture.PAPER));
    Assert.IsTrue(Godzilla.Instance.Beats(Gesture.SCISSORS));
}

Now imagine if the Gesture enum was part of a library… Nothing would prevent user code from providing a Godzilla instance wherever a Gesture is asked…

There are several ways to secure this implementation :

  1. The logic could be provided as embedded data in the registration or the enum (using a lambda expression). Although this is the solution I would prefer (“composition over inheritance”, see the Manifesto for Not Only Object-Oriented Development), this would not be a real polymorphic behaviour anymore !
  2. If we want to solve this using polymorphism, this is what I came up with. I added the following two “Checked” methods and the IsRegistered property in the base class :
private bool IsRegistered
{
    get { return registeredInstances.Values.Contains(this); }
}

protected TEnum Checked(TEnum value)
{
    if (!value.IsRegistered)
        throw new UnregisteredEnumException(
            "This enum is not registered");

    return value;
}

protected void Checked(Action a)
{
    if (!IsRegistered)
        throw new UnregisteredEnumException(
            "This enum is not registered");

    a.Invoke();
}

protected TReturn Checked<TReturn>(Func<TReturn> f)
{
    if (!IsRegistered)
        throw new UnregisteredEnumException(
            "This enum is not registered");

    return f.Invoke();
}

Using these new methods, here is how we could rewrite the previous “Godzilla” sample :

public class CheckedGesture : PolymorphicEnum<CheckedGesture>
{
    public static CheckedGesture ROCK = Register<RockGesture>();
    public static CheckedGesture PAPER = Register();
    public static CheckedGesture SCISSORS = Register();

    // we can implement with the integer representation
    public bool Beats(CheckedGesture other)
    {
        return Checked(() => this.BeatsImpl(Checked(other)));
    }

    protected virtual bool BeatsImpl(CheckedGesture other)
    {
        return this.Ordinal - other.Ordinal == 1;
    }

    private class RockGesture : CheckedGesture
    {
        protected override bool BeatsImpl(CheckedGesture other)
        {
            return other == SCISSORS;
        }
    }
}

And the method that can be overridden in the new Godzilla class in now the BeatsImpl one :

public class CagedGodzilla : CheckedGesture
{
    public static CagedGodzilla Instance = new CagedGodzilla();

    protected override bool BeatsImpl(CheckedGesture other)
    {
        return true;
    }
}

This now works correctly and the CagedGodzilla can’t be used in place of a CheckedGesture without throwing an UnregisteredEnumException. But this seems a little bit over-engineered, isn’t it ?

All of this horrible mess is available on my GitHub, along with the unit tests and the different steps of the implementation, which I’ve described in this post.

Posted in Syntax Puzzles | Tagged , , , | Comments Off