C# 从枚举中获取XmlEnumAttribute

C# 从枚举中获取XmlEnumAttribute,c#,enums,C#,Enums,我有: public enum Operation { /// <remarks/> [System.Xml.Serialization.XmlEnumAttribute("01")] Item01, /// <remarks/> [System.Xml.Serialization.XmlEnumAttribute("02")] Item02, /// <remarks/> [System.X

我有:

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

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("02")]
    Item02,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("03")]
    Item03,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("04")]
    Item04,
}

是否有更好的方法?

您必须使用反射来获取属性值:

var value = Operation.Item02;

var attributeValue = ((XmlEnumAttribute)typeof(Operation)
                        .GetMember(value.ToString())[0]
                        .GetCustomAttributes(typeof(XmlEnumAttribute), false)[0])
                        .Name;

可以使用此扩展方法创建一个helper(静态)类

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

谢谢,;这对我很有用。我想把拉斐尔的回答扩展到一个更一般的场景。如果枚举代码是由xsd.exe从xsd生成的,则并非每个枚举都具有该属性。当您使用xsd枚举将字符串限制为特定的值列表时,可能会发生这种情况,其中一些值有空格,而另一些值没有空格。例如:

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

将发出C#序列化代码:

public enum fooEnum {

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("Foo Bar")]
    FooBar,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("Bar Foo")]
    BarFoo,

    /// <remarks/>
    JustPlainFoo,
 }
公共枚举fooEnum{
/// 
[System.Xml.Serialization.XmlEnumAttribute(“Foo-Bar”)]
福巴,
/// 
[System.Xml.Serialization.XmlEnumAttribute(“Bar-Foo”)]
巴福,
/// 
JustPlainFoo,
}
对于这种情况,预期为“JustPlainFoo”的客户端代码将失败。我对拉斐尔答案的看法如下:

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;
    }
公共静态字符串XmlEnumToString(此TEnum值),其中TEnum:struct,IConvertible
{
类型enumType=typeof(TEnum);
如果(!enumType.IsEnum)
返回null;
MemberInfo member=enumType.GetMember(value.ToString()).FirstOrDefault();
if(成员==null)
返回null;
XmlEnumAttribute属性=member.GetCustomAttributes(false).OfType().FirstOrDefault();
if(属性==null)
return member.Name;//在没有属性时回退到成员名称
返回属性.Name;
}

最后,我要指出,劳霍茨的意见不适用于本案;XmlEnumAttribute不会出现在生成的C#代码中,您只需点击回退代码。

多亏了所有成员。如果枚举包含成员“Equals”、“GetHashCode”、“GetType”或“ToString”,则这可能不起作用。您应该按MemberType=字段过滤enumType.GetMember的结果。@Rauhotz。但是,我想你会承认,这将是一个非常(非常)特殊的情况(更不用说是一个相当糟糕的想法)!我写这篇评论是因为我刚刚遇到了一个罕见的关于collegue的关系运算符枚举的案例。这种方法对我来说很有效,可以从第三方ServiceReference中检索XmlEnumAttribute的值。@Rauhotz可能会在这篇文章中添加一个答案,该答案会扩展到包括过滤掉那些可怕的,糟糕的枚举数名称?我有一些具有类似值的枚举,还有一个具有枚举类型变量的类。当我的输入字符串有空格时,如何设置对象中的枚举数据?@rohinMVP不确定这里的“输入字符串”是什么意思。如果要反序列化XML,应该自动执行此操作。您是否正在尝试(使用我的示例)在常规StringToXmlEnum函数中将“Bar-Foo”转换为fooEnum.BarFoo?这似乎是一个奇怪的接口设计,但您当然可以为单个硬编码类型编写一个静态方法来实现这一点。所以本质上是字符串到枚举的转换。我有两个枚举,其中多个值有一个空格。是的,我必须将“Bar Foo”转换为fooEnum。BarFoo@rohinMVP您应该能够迭代枚举值来构建字典对象并使用它。
public enum fooEnum {

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("Foo Bar")]
    FooBar,

    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("Bar Foo")]
    BarFoo,

    /// <remarks/>
    JustPlainFoo,
 }
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;
    }