Emulate Java Enums With Values in C# (Pt. 2, Improved With Conversion Operator Overload)

In a previous blog post, I demonstrated how Java’ enums that contain one or more values/objects can be emulated with C#. One thing bothered me, though: the switch statement and how inconvenient it was to determine the proper type. Worst of all, it was not type-safe. In my simple example, it was easy because I was using strings. Imagine your fake-enum does not contain a string to quickly identify the instance.

Well, there is a prettier workaround – and it involves an actual enum. I was thinking about how the same could be done in C++ and in C++, you can have type conversion operators. Then I searched if such a feature also exists in C#, and sure enough, it does.

The new class looks as follows.

public sealed class CharacterReplacementCode
{
    public enum Type
    {
        Colon, Pound, QuestionMark
    }

    public static readonly CharacterReplacementCode Colon = new CharacterReplacementCode(Type.Colon, ":", "&58;");
    // Other readonly's

    // IEnumerable<CharacterReplacementCode> Values

    public static implicit operator CharacterReplacementCode.Type(CharacterReplacementCode replacementCode) 
        => replacementCode.EnumType;

    public Type EnumType { get; private set; }
    // Other properties

    CharacterReplacementCode(Type type, string character, string code) 
        => (EnumType, Character, Replacement) = (type, character, code);

    // ToString
}

I have added a Type enum, and I have also added another property EnumType to hold that value. It is set when the readonly CharacterReplacementCode instances are defined. The important piece is the implicit operator with which a class instance can be converted to the respective enum value. It is the value that is set in the constructor.

The switch statement now looks almost like one would expect from switching an enum.

foreach (var code in CharacterReplacementCode.Values) {
    switch ((CharacterReplacementCode.Type)code) {
        case CharacterReplacementCode.Type.Colon:
            Console.WriteLine("COLON: " + code);
            break;
        case CharacterReplacementCode.Type.Pound:
            Console.WriteLine("POUND: " + code);
            break;
        case CharacterReplacementCode.Type.QuestionMark:
            Console.WriteLine("QUESTION: " + code);
            break;
    }
}

The only exception is casting from CharacterReplacementCode to CharacterReplacementCode.Type, but other than that, it works like a regular enum-switch. If you prefer, you can also define the enum outside of the class.

You can find the complete example on Github.

I hope this helps. Thank you for reading.

Epilogue

One more small note on the use-case: the sample I have shown here is simplistic, and using two strings may not show the full potential. Imagine writing a configurable system that initializes factories based on string values in a config file. I like to use enum literals to represent the configuration values and then associate further objects, like a specific factory or a service, with the enum. You are not restricted to using strings, as I have mentioned in my first blog post. An enum must not only be a "dumb" value, but it can also contain meaningful data.

Here is some pseudo-code:

public enum AudioConverterType {
    MP3(new Mp3Converter(), new Mp3TagWriter()),
    AAC(new AacConverter(), new AacTagWriter());

    private AudioConverterInterface converter;
    private TagWriterInterface tagWriter;

    // Constructor

    // Getter
}

Once you have determined the correct enum type from a configuration value, you immediately gain access to the conversion and tag-writer service. Another, maybe more traditional, approach would be the use of factories.

More pseudo-code.

public class AudioManagementFactory {
    public AudioConverterInterface getConverter(AudioConverterType enumType) {
        // Switch on enumType and return the correct converter
    }


    public TagWriterInterface getTagWriter(AudioConverterType enumType) {
        // Switch on enumType and return the correct tag-writer
    }
}

Use whatever floats your boat 🙂

One thought on “Emulate Java Enums With Values in C# (Pt. 2, Improved With Conversion Operator Overload)

Leave a Reply

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

WordPress.com Logo

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

Google photo

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

Twitter picture

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

Facebook photo

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

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.