Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
445 views
in Technique[技术] by (71.8m points)

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.

(但是问题是,当我要求AuthenticationMethod.FORMS而不是ID 1时,我需要单词“ FORMS”。)

I have found the following solution for this problem ( link ):

(我已经找到以下针对此问题的解决方案( link ):)

First I need to create a custom attribute called "StringValue":

(首先,我需要创建一个名为“ 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:

(当然,我需要一些东西来检索该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.

(我也尝试了一些具有字典和静态属性的方法,但这也不是更好。)

  ask by user29964 translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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<string, AuthenticationMethod> instance = new Dictionary<string,AuthenticationMethod>(); 
    • nb 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.

      (nb为了使“枚举成员”字段的初始化在调用实例构造函数时不会引发NullReferenceException,请确保将Dictionary字段放在类中的“枚举成员”字段之前。)

      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(); } 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...