Converting between different types of enum
s is quite easy and it typically works fine. For a while. But changed business requirements might require that you modify the enum
s, and it’s easy to forget a conversion somewhere.
So let’s say that you got these enum
s:
public enum AccountState
{
NotActivated,
Active,
RequiresReActivation
}
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
}
... and forget 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.
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:
Enums with Different Value Names
Sometimes, you have enum
s 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.