Problem
The following is a list of what I have:
public enum AuthenticationMethod
{
FORMS = 1,
WINDOWSAUTHENTICATION = 2,
SINGLESIGNON = 3
}
The issue is that when I ask for AuthenticationMethod, I need to include the phrase “FORMS.” NOT THE ID 1 BUT THE FORMS
For this problem, I found the following solution (link):
First, I need to make a “StringValue” custom attribute:
public class StringValue : System.Attribute
{
private readonly string _value;
public StringValue(string value)
{
_value = value;
}
public string Value
{
get { return _value; }
}
}
After that, I’ll be able to 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’ll need a way to get the 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;
}
}
Now I have the tools I need to generate a string value for an enumerator. Then I’ll be able to use it like this:
string valueOfAuthenticationMethod = StringEnum.GetStringValue(AuthenticationMethod.FORMS);
Now, all of these function great, but I find them to be a lot of work. I’m not sure if there’s a better way to do this.
I also tried using a dictionary and static properties, but that didn’t work out well.
Asked by user29964
Solution #1
Try type-safe-enum pattern.
public sealed class AuthenticationMethod {
private readonly String name;
private readonly int value;
public static readonly AuthenticationMethod FORMS = new AuthenticationMethod (1, "FORMS");
public static readonly AuthenticationMethod WINDOWSAUTHENTICATION = new AuthenticationMethod (2, "WINDOWS");
public static readonly AuthenticationMethod SINGLESIGNON = new AuthenticationMethod (3, "SSN");
private AuthenticationMethod(int value, String name){
this.name = name;
this.value = value;
}
public override String ToString(){
return name;
}
}
Update Type conversion can be done explicitly (or implicitly) in a number of ways.
Answered by Jakub Šturc
Solution #2
Use method
Enum.GetName(Type MyEnumType, object enumvariable)
in the same way (Assume Shipper is a defined Enum)
Shipper x = Shipper.FederalExpress;
string s = Enum.GetName(typeof(Shipper), x);
There are several other static methods on the Enum class that are also worth studying…
Answered by Charles Bretana
Solution #3
Using ToString, you can refer to the name rather than the value ()
Console.WriteLine("Auth method: {0}", AuthenticationMethod.Forms.ToString());
The documentation can be found here:
http://msdn.microsoft.com/en-us/library/16c1xs4z.aspx
…and if you name your enums in Pascal Case (like I do – ThisIsMyEnumValue = 1, for example), you can print the friendly form with a simple regex:
static string ToFriendlyCase(this string EnumString)
{
return Regex.Replace(EnumString, "(?!^)([A-Z])", " $1");
}
It may be called easily from any string:
Console.WriteLine("ConvertMyCrazyPascalCaseSentenceToFriendlyCase".ToFriendlyCase());
Outputs:
That saves you from having to create special characteristics and attach them to your enums or using lookup tables to marry an enum value with a friendly string, plus it’s self-managing and can be used on any Pascal Case string, making it far more reusable. Of course, it prevents you from using a friendly name other than the one provided by your solution.
However, for more complex circumstances, I prefer your original solution. You could take your approach a step further by making GetStringValue an extension method of your enum, which would eliminate the requirement to refer to it as StringEnum. GetStringValue…
public static string GetStringValue(this AuthenticationMethod value)
{
string output = null;
Type type = value.GetType();
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;
}
You could then easily get it directly from your enum instance:
Console.WriteLine(AuthenticationMethod.SSO.GetStringValue());
Answered by 7 revs
Solution #4
Unfortunately, getting characteristics on enums using reflection takes a long time:
Anyone know a simple way to access to custom attributes on an enum value, as seen in this question?
On enums, the.ToString() method is also rather sluggish.
Extension methods for enums can, however, be written:
public static string GetName( this MyEnum input ) {
switch ( input ) {
case MyEnum.WINDOWSAUTHENTICATION:
return "Windows";
//and so on
}
}
This isn’t ideal, but it’ll save time and eliminate the need for reflection for attributes or field names.
C#6 Update
If you know C#6, you can use the new nameof operator to get enum names. For example, nameof(MyEnum.WINDOWSAUTHENTICATION) will be translated to “WINDOWSAUTHENTICATION” at compile time, making it the fastest way to get enum names.
This will convert the explicit enum to an inlined constant, hence it will not work with enums stored in variables. So:
nameof(AuthenticationMethod.FORMS) == "FORMS"
But…
var myMethod = AuthenticationMethod.FORMS;
nameof(myMethod) == "myMethod"
Answered by Keith
Solution #5
I use the following extension method:
public static class AttributesHelperExtension
{
public static string ToDescription(this Enum value)
{
var da = (DescriptionAttribute[])(value.GetType().GetField(value.ToString())).GetCustomAttributes(typeof(DescriptionAttribute), false);
return da.Length > 0 ? da[0].Description : value.ToString();
}
}
Now add the following to the enum:
public enum AuthenticationMethod
{
[Description("FORMS")]
FORMS = 1,
[Description("WINDOWSAUTHENTICATION")]
WINDOWSAUTHENTICATION = 2,
[Description("SINGLESIGNON ")]
SINGLESIGNON = 3
}
When you call
AuthenticationMethod. FORMS. “FORMS” will be returned by ToDescription().
Answered by Mangesh Pimpalkar
Post is based on https://stackoverflow.com/questions/424366/string-representation-of-an-enum