Saturday 17 August 2019

c# - String representation of an Enum




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.


Answer



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
Explicit (or implicit) type conversion can be done by




  • adding static field with mapping



    private static readonly Dictionary instance = new Dictionary();




    • n.b. In order that the initialisation of the the "enum member" fields doesn't throw a NullReferenceException when calling the instance constructor, be sure to put the Dictionary field before the "enum member" fields in your class. This is because static field initialisers are called in declaration order, and before the static constructor, creating the weird and necessary but confusing situation that the instance constructor can be called before all static fields have been initialised, and before the static constructor is called.


  • filling this mapping in instance constructor



    instance[name] = this;

  • and adding user-defined type conversion operator



    public static explicit operator AuthenticationMethod(string str)

    {
    AuthenticationMethod result;
    if (instance.TryGetValue(str, out result))
    return result;
    else
    throw new InvalidCastException();
    }


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...