Мне нужна Родовая функция для получения имени или значения перечисления на основе свойства "Name" XmlEnumAttribute перечисления. Например, мне определили следующее перечисление:
Public Enum Currency
<XmlEnum("00")> CDN = 1
<XmlEnum("01")> USA= 2
<XmlEnum("02")> EUR= 3
<XmlEnum("03")> JPN= 4
End Enum
Первое перечисление значений Валюты равняется 1; перечислимое имя является "CDN"; и значение свойства Названия XMLEnumAttribute "00".
Если у меня есть перечисление значений, я могу получить значение "Названия" XmlEnumAttribute с помощью следующей родовой функции:
Public Function GetXmlAttrNameFromEnumValue(Of T)(ByVal pEnumVal As T) As String
Dim type As Type = pEnumVal.GetType
Dim info As FieldInfo = type.GetField([Enum].GetName(GetType(T), pEnumVal))
Dim att As XmlEnumAttribute = CType(info.GetCustomAttributes(GetType(XmlEnumAttribute), False)(0), XmlEnumAttribute) 'If there is an xmlattribute defined, return the name
Return att.Name
End Function
Так с помощью вышеупомянутой функции, я могу указать тип перечисления Валюты, передать значение 1, и возвращаемое значение будет "00".
То, в чем я нуждаюсь, является функцией, чтобы работать если противоположное. Если я сделал, чтобы XmlEnumAttribute Назвал значение "00", мне нужна функция для возврата перечисления Валюты со значением 1. Столь же полезный была бы функция, которая возвратит перечислимое имя "CDN". Я мог затем просто проанализировать это для получения перечисления значений.
Любая помощь ценилась бы.
Требование решить точно такую же проблему привело меня к этому вопросу и ответу. Поскольку я разрабатываю в VB.NET, я переписал решение CkH в VB и модифицировал его, чтобы использовать вашу GetXmlAttrNameFromEnumValue
функцию.
Public Shared Function GetCode(Of T)(ByVal value As String) As T
For Each o As Object In System.Enum.GetValues(GetType(T))
Dim enumValue As T = CType(o, T)
If GetXmlAttrNameFromEnumValue(Of T)(enumValue).Equals(value, StringComparison.OrdinalIgnoreCase) Then
Return CType(o, T)
End If
Next
Throw New ArgumentException("No code exists for type " + GetType(T).ToString() + " corresponding to value of " + value)
End Function
C# Version:
public static string GetXmlAttrNameFromEnumValue<T>(T pEnumVal)
{
// http://stackoverflow.com/q/3047125/194717
Type type = pEnumVal.GetType();
FieldInfo info = type.GetField(Enum.GetName(typeof(T), pEnumVal));
XmlEnumAttribute att = (XmlEnumAttribute)info.GetCustomAttributes(typeof(XmlEnumAttribute), false)[0];
//If there is an xmlattribute defined, return the name
return att.Name;
}
public static T GetCode<T>(string value)
{
// http://stackoverflow.com/a/3073272/194717
foreach (object o in System.Enum.GetValues(typeof(T)))
{
T enumValue = (T)o;
if (GetXmlAttrNameFromEnumValue<T>(enumValue).Equals(value, StringComparison.OrdinalIgnoreCase))
{
return (T)o;
}
}
throw new ArgumentException("No XmlEnumAttribute code exists for type " + typeof(T).ToString() + " corresponding to value of " + value);
}
Я делаю нечто подобное с настраиваемыми атрибутами и использую этот метод для получения EnumValue на основе значения атрибута. GetStringValue - это мой собственный метод, аналогичный приведенному выше примеру.
public static class Enums
{
public static T GetCode<T>(string value)
{
foreach (object o in System.Enum.GetValues(typeof(T)))
{
if (((Enum)o).GetStringValue().Equals(value, StringComparison.OrdinalIgnoreCase))
return (T)o;
}
throw new ArgumentException("No code exists for type " + typeof(T).ToString() + " corresponding to value of " + value);
}
}
Для всего процесса, который я использую, проверьте этот пост и ответы: Расширение Enums, Overkill?
Извините, это на C #, только что понял, что вы использовали VB.NET выше.