Get XmlEnumAttribute from enum

前端 未结 3 1702
感动是毒
感动是毒 2020-12-30 02:52

I have enum:

public enum Operation {
    /// 
    [System.Xml.Serialization.XmlEnumAttribute(\"01\")]
    Item01,

    /// 
          


        
相关标签:
3条回答
  • 2020-12-30 03:42

    You could create an helper (static) class, with this extension method

    public static string GetXmlEnumAttributeValueFromEnum<TEnum>(this TEnum value) where TEnum : struct, IConvertible
    {
        var enumType = typeof(TEnum);
        if (!enumType.IsEnum) return null;//or string.Empty, or throw exception
    
        var member = enumType.GetMember(value.ToString()).FirstOrDefault();
        if (member == null) return null;//or string.Empty, or throw exception
    
        var attribute = member.GetCustomAttributes(false).OfType<XmlEnumAttribute>().FirstOrDefault();
        if (attribute == null) return null;//or string.Empty, or throw exception
        return attribute.Name;
    }
    

    usage

    var res = Operation.Item1;
    var result = res.GetXmlAttributeValueFromEnum();
    
    0 讨论(0)
  • 2020-12-30 03:42

    Thanks; this is useful to me. I'd like to extend Raphael's answer to a slightly more general scenario. If the enum code is generated from xsd by xsd.exe, not every enum will have the attribute. This may happen when you're using xsd enums to limit strings to a specific list of values, some of which have spaces and some of which don't. For example:

    <xs:simpleType name="fooEnum">
     <xs:restriction base="xs:string">
      <xs:enumeration value="Foo Bar" />
      <xs:enumeration value="Bar Foo" />
      <xs:enumeration value="JustPlainFoo" />
     </xs:restriction>
    </xs:simpleType>
    

    will emit the C# serialization code:

    public enum fooEnum {
    
        /// <remarks/>
        [System.Xml.Serialization.XmlEnumAttribute("Foo Bar")]
        FooBar,
    
        /// <remarks/>
        [System.Xml.Serialization.XmlEnumAttribute("Bar Foo")]
        BarFoo,
    
        /// <remarks/>
        JustPlainFoo,
     }
    

    For this case, client code expecting "JustPlainFoo" will fail. My version of Raphael's answer is then as follows:

    public static string XmlEnumToString<TEnum>(this TEnum value) where TEnum : struct, IConvertible
        {
            Type enumType = typeof(TEnum);
            if (!enumType.IsEnum)
                return null;
    
            MemberInfo member = enumType.GetMember(value.ToString()).FirstOrDefault();
            if (member == null)
                return null;
    
            XmlEnumAttribute attribute = member.GetCustomAttributes(false).OfType<XmlEnumAttribute>().FirstOrDefault();
            if (attribute == null)
                return member.Name; // Fallback to the member name when there's no attribute
    
            return attribute.Name;
        }
    

    Finally, I'll note that Rauhotz's commment won't apply to this case; the XmlEnumAttribute won't be there in the generated C# code and you'll just hit the fallback code.

    0 讨论(0)
  • 2020-12-30 03:54

    You have to use Reflection to get the attribute value:

    var value = Operation.Item02;
    
    var attributeValue = ((XmlEnumAttribute)typeof(Operation)
                            .GetMember(value.ToString())[0]
                            .GetCustomAttributes(typeof(XmlEnumAttribute), false)[0])
                            .Name;
    
    0 讨论(0)
提交回复
热议问题