我有以下列举:

public enum AuthenticationMethod
{
    FORMS = 1,
    WINDOWSAUTHENTICATION = 2,
    SINGLESIGNON = 3
}

然而问题是,当我请求AuthenticationMethod时,我需要“FORMS”这个词。表单而不是id

对于这个问题,我找到了以下解决方案(链接):

首先,我需要创建一个自定义属性“StringValue”:

public class StringValue : System.Attribute
{
    private readonly string _value;

    public StringValue(string value)
    {
        _value = value;
    }

    public string Value
    {
        get { return _value; }
    }

}

然后我可以将这个属性添加到我的枚举器中:

public enum AuthenticationMethod
{
    [StringValue("FORMS")]
    FORMS = 1,
    [StringValue("WINDOWS")]
    WINDOWSAUTHENTICATION = 2,
    [StringValue("SSO")]
    SINGLESIGNON = 3
}

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

很好,现在我已经有了工具来获取枚举器的字符串值。 然后我可以这样使用它:

string valueOfAuthenticationMethod = StringEnum.GetStringValue(AuthenticationMethod.FORMS);

好的,现在所有这些工作就像一个魅力,但我发现它有很多工作。我想知道有没有更好的解决办法。

我还尝试了一些字典和静态属性,但这也不是更好。


当前回答

如果我理解正确,你可以简单地使用.ToString()从值中检索enum的名称(假设它已经被转换为enum); 如果你有裸整型(比如从数据库或其他地方),你可以先将它强制转换为枚举。 下面的两个方法都将获得枚举名称。

AuthenticationMethod myCurrentSetting = AuthenticationMethod.FORMS;
Console.WriteLine(myCurrentSetting); // Prints: FORMS
string name = Enum.GetNames(typeof(AuthenticationMethod))[(int)myCurrentSetting-1];
Console.WriteLine(name); // Prints: FORMS

但是请记住,第二种技术假设您使用的是int型,并且您的索引基于1(而不是基于0)。相比之下,GetNames函数也相当繁重,每次调用它都要生成一个完整的数组。 正如您在第一种技术中看到的,. tostring()实际上是隐式调用的。 这两个问题都已经在答案中提到了,当然,我只是想澄清它们之间的区别。

其他回答

使用对象枚举. parse(系统。类型枚举类型,字符串值,bool ignoreCase);从http://blogs.msdn.com/b/tims/archive/2004/04/02/106310.aspx获取

如果我理解正确,你可以简单地使用.ToString()从值中检索enum的名称(假设它已经被转换为enum); 如果你有裸整型(比如从数据库或其他地方),你可以先将它强制转换为枚举。 下面的两个方法都将获得枚举名称。

AuthenticationMethod myCurrentSetting = AuthenticationMethod.FORMS;
Console.WriteLine(myCurrentSetting); // Prints: FORMS
string name = Enum.GetNames(typeof(AuthenticationMethod))[(int)myCurrentSetting-1];
Console.WriteLine(name); // Prints: FORMS

但是请记住,第二种技术假设您使用的是int型,并且您的索引基于1(而不是基于0)。相比之下,GetNames函数也相当繁重,每次调用它都要生成一个完整的数组。 正如您在第一种技术中看到的,. tostring()实际上是隐式调用的。 这两个问题都已经在答案中提到了,当然,我只是想澄清它们之间的区别。

选项1:

public sealed class FormsAuth
{
     public override string ToString{return "Forms Authtentication";}
}
public sealed class WindowsAuth
{
     public override string ToString{return "Windows Authtentication";}
}

public sealed class SsoAuth
{
     public override string ToString{return "SSO";}
}

然后

object auth = new SsoAuth(); //or whatever

//...
//...
// blablabla

DoSomethingWithTheAuth(auth.ToString());

选项2:

public enum AuthenticationMethod
{
        FORMS = 1,
        WINDOWSAUTHENTICATION = 2,
        SINGLESIGNON = 3
}

public class MyClass
{
    private Dictionary<AuthenticationMethod, String> map = new Dictionary<AuthenticationMethod, String>();
    public MyClass()
    {
         map.Add(AuthenticationMethod.FORMS,"Forms Authentication");
         map.Add(AuthenticationMethod.WINDOWSAUTHENTICATION ,"Windows Authentication");
         map.Add(AuthenticationMethod.SINGLESIGNON ,"SSo Authentication");
    }
}

这里还有另一种方法来完成将字符串与枚举关联的任务:

struct DATABASE {
    public enum enums {NOTCONNECTED, CONNECTED, ERROR}
    static List<string> strings =
        new List<string>() {"Not Connected", "Connected", "Error"};

    public string GetString(DATABASE.enums value) {
        return strings[(int)value];
    }
}

这个方法是这样调用的:

public FormMain() {
    DATABASE dbEnum;

    string enumName = dbEnum.GetString(DATABASE.enums.NOTCONNECTED);
}

您可以将相关枚举分组到它们自己的结构中。由于此方法使用枚举类型,所以在调用GetString()时可以使用智能感知来显示枚举列表。

可以选择在DATABASE结构上使用new操作符。不使用它意味着在第一次GetString()调用之前不会分配字符串列表。

我支持Harvey,但不用const。我可以混合匹配字符串,int,等等。

public class xlsLayout
{
    public int xlHeaderRow = 1;
    public int xlFirstDataRow = 2;
    public int xlSkipLinesBetweenFiles = 1; //so 0 would mean don't skip
    public string xlFileColumn = "A";
    public string xlFieldColumn = "B";
    public string xlFreindlyNameColumn = "C";
    public string xlHelpTextColumn = "D";
}

然后……

public partial class Form1 : Form
{
    xlsLayout xlLayout = new xlsLayout();

    xl.SetCell(xlLayout.xlFileColumn, xlLayout.xlHeaderRow, "File Name");
    xl.SetCell(xlLayout.xlFieldColumn, xlLayout.xlHeaderRow, "Code field name");
    xl.SetCell(xlLayout.xlFreindlyNameColumn, xlLayout.xlHeaderRow, "Freindly name");
    xl.SetCell(xlLayout.xlHelpTextColumn, xlLayout.xlHeaderRow, "Inline Help Text");
}