使用注释将enum转换为字符串(反之亦然)

本文关键字:字符串 反之亦然 转换 注释 enum | 更新日期: 2023-09-27 18:09:47

通常,当我发现自己需要将枚举转换为字符串或反之亦然时,我通常利用Description属性。

例如,如果我有以下enum:

public enum QueryOperations
{
     [Description("eq")]
     Equals,
     [Description("gt")]
     GreaterThan,
     [Description("lt")]
     LessThan
}

我将使用DescriptionAttribute的值将QueryOperations.GreaterThan转换为字符串,也就是说,它将被转换为"gt"

同样,如果我要将"lt"转换为QueryOperations,我将最终得到QueryOperations.LessThan

我真的很喜欢这种方法,到目前为止从未让我失望过。我认为它是灵活的,易于理解的,它是从枚举的值名解耦。

然而,引用MSDN, a DescriptionAttribute:

[…指定属性或事件的描述。

示例如下:

[Description("The image associated with the control"),Category("Appearance")] 
public Image MyImage { get; set; }

这让我很困扰,因为DescriptionAttribute的目的似乎在语义上与我使用它的目的不同。

使用属性转换枚举既不愚蠢也不疯狂,所以我的问题是:

是否有专门为这种情况设计的属性?

类似:

public enum QueryOperations
{
    [StringRepresentation("eq")]
    Equals,
    //...
}

使用注释将enum转换为字符串(反之亦然)

简短的回答是没有,没有任何内置的东西。

我认为,如果您呈现的用例是您需要做的典型用例,那么您最好创建一个自定义属性。Description属性可以按照您使用它的方式使用,但是正如您已经提到的,它实际上是一个人类可读的描述。

例如,你可以这样做:

    public class StringRepresentationAttribute : Attribute
    {
        public StringRepresentationAttribute(string stringRep)
        {
            this._stringRep = stringRep;
        }
        public string StringRepresentation { get { return _stringRep; } }
        private readonly string _stringRep;
        public override string ToString()
        {
            return StringRepresentation;
        }
    }

然后像这样做一个扩展方法:

public static string GetStringRepresentation(this Enum en)
        {
            Type type = en.GetType();
            MemberInfo[] memInfo = type.GetMember(en.ToString());
            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(StringRepresentationAttribute), false);
                if (attrs != null && attrs.Length > 0)
                {
                    return ((StringRepresentationAttribute)attrs[0]).StringRepresentation;
                }
            }
            return en.ToString();
        }

你的枚举变成:

public enum QueryOperations
{
     [StringRepresentation("eq")]
     Equals,
     [StringRepresentation("gt")]
     GreaterThan,
     [StringRepresentation("lt")]
     LessThan
}

现在你可以:

string operatorAsString = QueryOperations.LessThan.GetStringRepresentation();

我喜欢使用扩展方法。本文http://weblogs.asp.net/grantbarrington/enumhelper-getting-a-friendly-description-from-an-enum更深入地讨论了这个主题

下面是扩展方法的快速浏览:

 public static class EnumHelper
    {
        /// <summary>
        /// Retrieve the description on the enum, e.g.
        /// [Description("Bright Pink")]
        /// BrightPink = 2,
        /// Then when you pass in the enum, it will retrieve the description
        /// </summary>
        /// <param name="en">The Enumeration</param>
        /// <returns>A string representing the friendly name</returns>
        public static string GetDescription(Enum en)
        {
            Type type = en.GetType();
            MemberInfo[] memInfo = type.GetMember(en.ToString());
            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (attrs != null && attrs.Length > 0)
                {
                    return ((DescriptionAttribute)attrs[0]).Description;
                }
            }
            return en.ToString();
        }
    }

你会得到这样的描述:

MyEnum.EnumsValue.GetDescription();
反过来,你可以使用。net框架中内置的Parse或TryParse:
//Parse
MyEnum enumValue = (MyEnum) Enum.Parse(typeof(MyEnum), enumValueString);
//TryParse
MyEnum enumValue;
Enum.TryParse(enumValueString, out enumValue));