我有以下列举:

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

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

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


当前回答

当我遇到这样的问题时,我首先会试图找到以下几个问题的答案:

枚举值的名称是否足够友好,或者我需要提供更友好的名称? 我需要往返吗?也就是说,我是否需要将文本值解析为枚举值? 这是我需要为我的项目中的许多枚举做的事情,还是只有一个? 我将在什么样的UI元素中呈现这些信息-特别是,我将绑定到UI,还是使用属性表? 这需要本地化吗?

最简单的方法是使用Enum。GetValue(并使用枚举. parse支持往返)。正如Steve Mitcham所建议的那样,构建一个TypeConverter来支持UI绑定通常也是值得的。(在使用属性表时,没有必要构建TypeConverter,这是属性表的优点之一。尽管天晓得他们也有自己的问题。)

一般来说,如果上述问题的答案表明这是行不通的,我的下一步是创建和填充一个静态Dictionary<MyEnum,字符串>,或者可能是一个Dictionary<Type, Dictionary<int,字符串>>。我倾向于跳过中间的用属性装饰代码的步骤,因为接下来通常需要在部署后更改友好值(通常,但不总是,因为本地化)。

其他回答

我如何解决这个扩展方法:

using System.ComponentModel;
public static string GetDescription(this Enum value)
{
    var descriptionAttribute = (DescriptionAttribute)value.GetType()
        .GetField(value.ToString())
        .GetCustomAttributes(false)
        .Where(a => a is DescriptionAttribute)
        .FirstOrDefault();

    return descriptionAttribute != null ? descriptionAttribute.Description : value.ToString();
}

枚举:

public enum OrderType
{
    None = 0,
    [Description("New Card")]
    NewCard = 1,
    [Description("Reload")]
    Refill = 2
}

用法(其中o.OrderType是一个与enum同名的属性):

o.OrderType.GetDescription()

这给了我一个字符串的“新卡”或“重载”,而不是实际的enum值NewCard和重新填充。

我想把这篇文章作为下面引用的帖子的评论,但不能,因为我没有足够的代表。代码包含一个错误,我想向试图使用这个解决方案的个人指出这一点:

[TypeConverter typeof (CustomEnumTypeConverter (typeof (MyEnum))) public enum MyEnum { //自定义类型转换器将使用description属性 [描述(“自定义描述”)] ValueWithCustomDescription, //这将完全暴露。 确切的 }

应该是

[TypeConverter(typeof(CustomEnumTypeConverter<MyEnum>))]
public enum MyEnum
{
  // The custom type converter will use the description attribute
  [Description("A custom description")]
  ValueWithCustomDescription,

  // This will be exposed exactly.
  Exact
}

我使用一个扩展方法:

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

现在用:

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

当你打电话时

AuthenticationMethod.FORMS.ToDescription()将得到“FORMS”。

好吧,在阅读了以上所有内容后,我觉得这些家伙将枚举数转换为字符串的问题过于复杂了。 我喜欢在枚举字段上拥有属性的想法,但我认为属性主要用于元数据,但在你的情况下,我认为你所需要的只是某种本地化。

public enum Color 
{ Red = 1, Green = 2, Blue = 3}


public static EnumUtils 
{
   public static string GetEnumResourceString(object enumValue)
    {
        Type enumType = enumValue.GetType();
        string value = Enum.GetName(enumValue.GetType(), enumValue);
        string resourceKey = String.Format("{0}_{1}", enumType.Name, value);
        string result = Resources.Enums.ResourceManager.GetString(resourceKey);
        if (string.IsNullOrEmpty(result))
        {
            result = String.Format("{0}", value);
        }
        return result;
    }
}

现在如果我们尝试调用上面的方法,我们可以这样调用它

public void Foo()
{
  var col = Color.Red;
  Console.WriteLine (EnumUtils.GetEnumResourceString (col));
}

您所需要做的就是创建一个包含所有枚举值和相应字符串的资源文件

Resource Name          Resource Value
Color_Red              My String Color in Red
Color_Blue             Blueeey
Color_Green            Hulk Color

这样做的好处是,如果您需要本地化应用程序,它将非常有用,因为您所需要做的只是用新语言创建另一个资源文件!和Voe-la !

老帖子,但是…

这个问题的答案其实很简单。使用enumel . tostring()函数

这个函数有6个重载,你可以使用enumenumtostring ("F")或enumenumtostring()来返回字符串值。没必要为其他事操心。这是一个正在运行的演示

注意,这个解决方案可能不适用于所有编译器(这个演示没有像预期的那样工作),但至少它适用于最新的编译器。