Получить XmlEnumAttribute из перечисления
У меня есть перечисление:
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,
}
Как я могу получить значение XmlEnumAttribute?
Я пытаюсь:
var res = Operation.Item1;
var result = (res.GetType().GetField("Item01").GetCustomAttributes(typeof(XmlEnumAttribute), true)[0] as XmlEnumAttribute).Name;
Может быть лучший метод?
Ответы
Ответ 1
Вы можете создать вспомогательный (статический) класс с помощью этого метода расширения
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;
}
использование
var res = Operation.Item1;
var result = res.GetXmlAttributeValueFromEnum();
Ответ 2
Вы должны использовать Reflection для получения значения атрибута:
var value = Operation.Item02;
var attributeValue = ((XmlEnumAttribute)typeof(Operation)
.GetMember(value.ToString())[0]
.GetCustomAttributes(typeof(XmlEnumAttribute), false)[0])
.Name;
Ответ 3
Спасибо; это полезно для меня. Я бы хотел расширить ответ рафаэля на более общий сценарий. Если код перечисления сгенерирован из xsd программой xsd.exe, не у каждого перечисления будет этот атрибут. Это может произойти, когда вы используете перечисления 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>
выдаст код сериализации С#:
public enum fooEnum {
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("Foo Bar")]
FooBar,
/// <remarks/>
[System.Xml.Serialization.XmlEnumAttribute("Bar Foo")]
BarFoo,
/// <remarks/>
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 no attribute
return attribute.Name;
}
Наконец, я отмечу, что комментарий Rauhotz не применим к этому делу; Атрибут XmlEnumAttribute не будет присутствовать в сгенерированном коде С#, и вы просто нажмете запасной код.