Retrieve enum value based on XmlEnumAttribute name value

匿名 (未验证) 提交于 2019-12-03 01:23:02

问题:

I need a Generic function to retrieve the name or value of an enum based on the XmlEnumAttribute "Name" property of the enum. For example I have the following enum defined:

Public Enum Currency     CDN = 1     USA= 2     EUR= 3     JPN= 4 End Enum 

The first Currency enum value is 1; the enum name is "CDN"; and the XMLEnumAttribute Name property value is "00".

If I have the enum value, I can retrieve the XmlEnumAttribute "Name" value using the following generic function:

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 

So using the above function, I can specify the Currency enum type, pass a value of 1, and the return value will be "00".

What I need is a function to perform if the opposite. If I have the XmlEnumAttribute Name value "00", I need a function to return a Currency enum with a value of 1. Just as useful would be a function that would return the enum name "CDN". I could then simply parse this to get the enum value.

Any assistance would be appreciated.

回答1:

A requirement to solve this exact same problem led me to this question and answer. As I develop in VB.NET, I rewrote CkH's solution into VB and modified it to use your GetXmlAttrNameFromEnumValue function.

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 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(string value) {     // http://stackoverflow.com/a/3073272/194717     foreach (object o in System.Enum.GetValues(typeof(T)))     {         T enumValue = (T)o;         if (GetXmlAttrNameFromEnumValue(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); } 


回答2:

I do something similar with custom attributes and I use this method to get the EnumValue based on the Attribute Value. GetStringValue is my custom method, similar to your example above.

public static class Enums  {      public static T GetCode(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);      }  }   

For the whole process I use check this post and the answers: Extending Enums, Overkill?

Sorry this is in C#, just realized you were using VB.NET above.



回答3:

Slightly modified from: http://www.wackylabs.net/2006/06/getting-the-xmlenumattribute-value-for-an-enum-field/

public static string ToString2 (this Enum e) {     // Get the Type of the enum     Type t = e.GetType ();      // Get the FieldInfo for the member field with the enums name     FieldInfo info = t.GetField (e.ToString ("G"));      // Check to see if the XmlEnumAttribute is defined on this field     if (!info.IsDefined (typeof (XmlEnumAttribute), false)) {         // If no XmlEnumAttribute then return the string version of the enum.         return e.ToString ("G");     }      // Get the XmlEnumAttribute     object[] o = info.GetCustomAttributes (typeof (XmlEnumAttribute), false);     XmlEnumAttribute att = (XmlEnumAttribute)o[0];     return att.Name; } 


回答4:

@Dean, @Jason and @Camron, thank you for your solutions. Your solutions helped me in solving my problem, where, given an XmlEnumAttribute name, the actual enum value was needed.

My variant is mentioned here.



回答5:

Here's a variation that generates a dictionary from the enum, allowing you to potentially cache the reflection part of it should you need to use it a lot.

///  /// Generates a dictionary allowing you to get the csharp enum value /// from the string value in the matching XmlEnumAttribute. /// You need this to be able to dynamically set entries from a xsd:enumeration /// when you've used xsd.exe to generate a .cs from the xsd. /// https://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx ///  /// The xml enum type you want the mapping for /// Mapping dictionary from attribute values (key) to the actual enum values /// T must be an enum private static Dictionary GetEnumMap() where T : struct, IConvertible {         if (!typeof(T).IsEnum)         {                 throw new ArgumentException("T must be an enum");         }         var members = typeof(T).GetMembers();         var map = new Dictionary();         foreach (var member in members)         {                 var enumAttrib = member.GetCustomAttributes(typeof(XmlEnumAttribute), false).FirstOrDefault() as XmlEnumAttribute;                 if (enumAttrib == null)                 {                         continue;                 }                 var xmlEnumValue = enumAttrib.Name;                 var enumVal = ((FieldInfo)member).GetRawConstantValue();                 map.Add(xmlEnumValue, (T)enumVal);         }         return map; } 

usage:

var map = GetEnumMap(); return map["02"]; // returns Currency.EUR 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!