I have the following enumeration:
public enum AuthenticationMethod
{
FORMS = 1,
WINDOWSAUTHENTICATION = 2,
SINGLESIGNON = 3
}
The problem however is that I need the word "FORMS" when I ask for AuthenticationMethod.FORMS and not the id 1.
I have found the following solution for this problem (link):
First I need to create a custom attribute called "StringValue":
public class StringValue : System.Attribute
{
private readonly string _value;
public StringValue(string value)
{
_value = value;
}
public string Value
{
get { return _value; }
}
}
Then I can add this attribute to my enumerator:
public enum AuthenticationMethod
{
[StringValue("FORMS")]
FORMS = 1,
[StringValue("WINDOWS")]
WINDOWSAUTHENTICATION = 2,
[StringValue("SSO")]
SINGLESIGNON = 3
}
And of course I need something to retrieve that StringValue:
public static class StringEnum
{
public static string GetStringValue(Enum value)
{
string output = null;
Type type = value.GetType();
//Check first in our cached results...
//Look for our 'StringValueAttribute'
//in the field's custom attributes
FieldInfo fi = type.GetField(value.ToString());
StringValue[] attrs =
fi.GetCustomAttributes(typeof(StringValue),
false) as StringValue[];
if (attrs.Length > 0)
{
output = attrs[0].Value;
}
return output;
}
}
Good now I've got the tools to get a string value for an enumerator. I can then use it like this:
string valueOfAuthenticationMethod = StringEnum.GetStringValue(AuthenticationMethod.FORMS);
Okay now all of these work like a charm but I find it a whole lot of work. I was wondering if there is a better solution for this.
I also tried something with a dictionary and static properties but that wasn't better either.
Very simple solution to this with .Net 4.0 and above. No other code is needed.
To get the string about just use:
or
The value will be "Active" or "Archived".
To see the different string formats (the "f" from above) when calling
Enum.ToString
see this Enumeration Format Strings pageIf you've come here looking to implement a simple "Enum" but whose values are strings instead of ints, here is the simplest solution:
Implementation:
Here is yet another way to accomplish the task of associating strings with enums:
This method is called like this:
You can group related enums in their own struct. Since this method uses the enum type, you can use Intellisense to display the list of enums when making the
GetString()
call.You can optionally use the new operator on the
DATABASE
struct. Not using it means the stringsList
is not allocated until the firstGetString()
call is made.When I'm confronted with this problem, there are a couple of questions that I try to find the answers to first:
The simplest way to do this is with
Enum.GetValue
(and support round-tripping usingEnum.Parse
). It's also often worth building aTypeConverter
, as Steve Mitcham suggests, to support UI binding. (It's not necessary to build aTypeConverter
when you're using property sheets, which is one of the nice things about property sheets. Though lord knows they have their own issues.)In general, if the answers to the above questions suggest that's not going to work, my next step is to create and populate a static
Dictionary<MyEnum, string>
, or possibly aDictionary<Type, Dictionary<int, string>>
. I tend to skip the intermediate decorate-the-code-with-attributes step because what's usually coming down the pike next is the need to change the friendly values after deployment (often, but not always, because of localization).If you think about the problem we're trying to solve, it's not an enum we need at all. We need an object that allows a certain number of values to be associated with eachother; in other words, to define a class.
Jakub Šturc's type-safe enum pattern is the best option I see here.
Look at it:
old post but...
The answer to this may actually be very simple. Use Enum.ToString() function
There are 6 overloads of this function, you can use Enum.Tostring("F") or Enum.ToString() to return the string value. No need to bother with anything else. Here is a working Demo
Note that this solution may not work for all compilers (this demo does not work as expected) but at least it works for the latest compiler.