Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

How to safely convert enums

, 17 Jul 2014
Rate this:
Please Sign up or sign in to vote.
Converting between different types of enums is quite easy and it typically works fine. For a while. But changed business requirements might require that you modify the enums, and it’s easy to forget a conversion somewhere. So let’s say that … Continue reading →

Converting between different types of enums is quite easy and it typically works fine. For a while. But changed business requirements might require that you modify the enums, and it’s easy to forget a conversion somewhere.

So let’s say that you got these enums:

//domain enum
public enum AccountState
{
    NotActivated,
    Active,
    RequiresReActivation
}

//DTO enum
public enum QueryAccountState
{
    NotActivated,
    Active,
    RequiresReActivation
}

A conversion is straight forward:

class Program
{
    static void Main(string[] args)
    {
        var queryState = (QueryAccountState) AccountState.Locked;
        Console.WriteLine(queryState);
    }
}

However, if you later introduce a new state in the domain model:

public enum AccountState
{
    NotActivated,
    Active,
    RequiresReActivation,
    Locked // <--- new state
}

.. and forgot that in the QueryAccountState your code will still work fine:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("domain: " + AccountState.Locked);
        Console.WriteLine("DTO:    "+  (QueryAccountState)AccountState.Locked);
    }
}

The problem is that the code will still compile and return zero errors.

screenshot

The queryState variable will contain the value three and any comparison with the QueryAccountState enum will silently fail (due to the fact that the value is not a part of the enum).

Here is a simple test:

public enum AccountState
{
    NotActivated,
    Active,
    RequiresReActivation,
    Locked
}

public enum QueryAccountState
{
    NotActivated,
    Active,
    RequiresReActivation,

}

class Program
{
    static void Main(string[] args)
    {
        var queryState = (QueryAccountState) AccountState.Locked;
        if (queryState == QueryAccountState.Active)
            Console.WriteLine("Active");
        if (queryState == QueryAccountState.NotActivated)
            Console.WriteLine("NotActivated");
        if (queryState == QueryAccountState.RequiresReActivation)
            Console.WriteLine("RequiresReActivation");
    }
}

.. that code will print nothing.

Using string conversion

A more solid approach is to convert the value to a string and then let the enum parse the string:

class Program
{
    static void Main(string[] args)
    {
        var domainState = AccountState.Locked;

        QueryAccountState queryState;
        if (!Enum.TryParse(domainState.ToString(), out queryState))
            throw new FormatException("Value '" + domainState + "' do not exist in the QueryAccountState enum.");

    }
}

Result:

screenshot2

Enums with different value names

Sometimes you have enums that have different value names. You typically convert them using a switch statement:

private LastTriggerAction ConvertLastAction(Api.Triggers.Commands.LastTriggerAction lastTriggerAction)
{
    switch (lastTriggerAction)
    {
        case Api.Triggers.Commands.LastTriggerAction.AbortTrigger:
            return LastTriggerAction.Revoke;
        case Api.Triggers.Commands.LastTriggerAction.ExecuteActions:
            return LastTriggerAction.Grant;
    }
}

However, do not forget to add a default statement to catch differences:

private LastTriggerAction ConvertLastAction(Api.Triggers.Commands.LastTriggerAction lastTriggerAction)
{
    switch (lastTriggerAction)
    {
        case Api.Triggers.Commands.LastTriggerAction.AbortTrigger:
            return LastTriggerAction.Revoke;
        case Api.Triggers.Commands.LastTriggerAction.ExecuteActions:
            return LastTriggerAction.Grant;
        default:
            throw new FormatException("Value '" + lastTriggerAction + "' do not exist in the LastTriggerAction enum.");

    }
}

Summary

So if you are doing enum conversions try to use string conversions or switch statements with a default option to be sure that the application will not stop working in future versions.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

Share

About the Author

jgauffin
Founder Gauffin Interactive AB
Sweden Sweden
Founder of OneTrueError, a .NET service which captures, analyzes and provide possible solutions for exceptions.
 
blog | twitter
Follow on   Twitter   LinkedIn

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web01 | 2.8.140916.1 | Last Updated 17 Jul 2014
Article Copyright 2014 by jgauffin
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid