You can't assign an enum value to a string to start with. You'd have to call ToString()
, which would convert Country.UnitedKingdom
to "UnitedKingdom".
Two options suggest themselves:
- Create a
Dictionary<Country, string>
- A switch statement
- Decorate each value with an attribute, and load that with reflection
Comments about each of them...
Sample code for Dictionary<Country,string>
using System;
using System.Collections.Generic;
enum Country
{
UnitedKingdom,
UnitedStates,
France,
Portugal
}
class Test
{
static readonly Dictionary<Country, string> CountryNames =
new Dictionary<Country, string>
{
{ Country.UnitedKingdom, "UK" },
{ Country.UnitedStates, "US" },
};
static string ConvertCountry(Country country)
{
string name;
return (CountryNames.TryGetValue(country, out name))
? name : country.ToString();
}
static void Main()
{
Console.WriteLine(ConvertCountry(Country.UnitedKingdom));
Console.WriteLine(ConvertCountry(Country.UnitedStates));
Console.WriteLine(ConvertCountry(Country.France));
}
}
You might want to put the logic of ConvertCountry
into an extension method. For example:
// Put this in a non-nested static class
public static string ToBriefName(this Country country)
{
string name;
return (CountryNames.TryGetValue(country, out name))
? name : country.ToString();
}
Then you could write:
string x = Country.UnitedKingdom.ToBriefName();
As mentioned in the comments, the default dictionary comparer will involve boxing, which is non-ideal. For a one-off, I'd live with that until I found it was a bottleneck. If I were doing this for multiple enums, I'd write a reusable class.
Switch statement
I agree with yshuditelu's answer suggesting using a switch
statement for relatively few cases. However, as each case is going to be a single statement, I'd personally change my coding style for this situation, to keep the code compact but readable:
public static string ToBriefName(this Country country)
{
switch (country)
{
case Country.UnitedKingdom: return "UK";
case Country.UnitedStates: return "US";
default: return country.ToString();
}
}
You can add more cases to this without it getting too huge, and it's easy to cast your eyes across from enum value to the return value.
DescriptionAttribute
The point Rado made about the code for DescriptionAttribute
being reusable is a good one, but in that case I'd recommend against using reflection every time you need to get a value. I'd probably write a generic static class to hold a lookup table (probably a Dictionary
, possibly with a custom comparer as mentioned in the comments). Extension methods can't be defined in generic classes, so you'd probably end up with something like:
public static class EnumExtensions
{
public static string ToDescription<T>(this T value) where T : struct
{
return DescriptionLookup<T>.GetDescription(value);
}
private static class DescriptionLookup<T> where T : struct
{
static readonly Dictionary<T, string> Descriptions;
static DescriptionLookup()
{
// Initialize Descriptions here, and probably check
// that T is an enum
}
internal static string GetDescription(T value)
{
string description;
return Descriptions.TryGetValue(value, out description)
? description : value.ToString();
}
}
}