2012-05-02 11 views
16

Mam następujący kodKorzystanie EnumMemberAttribute i robi automatyczne konwersje strunowe

[DataContract] 
public enum StatusType 
{ 
    [EnumMember(Value = "A")] 
    All, 
    [EnumMember(Value = "I")] 
    InProcess, 
    [EnumMember(Value = "C")] 
    Complete, 
} 

Chciałbym wykonaj następujące czynności:

var s = "C"; 
StatusType status = SerializerHelper.ToEnum<StatusType>(s); //status is now StatusType.Complete 
string newString = SerializerHelper.ToEnumString<StatusType>(status); //newString is now "C" 

Zrobiłem drugą część używając DataContractSerializer (patrz kod poniżej), ale wydaje się, że dużo pracy.

Czy brakuje mi czegoś oczywistego? Pomysły? Dzięki.

public static string ToEnumString<T>(T type) 
    { 
     string s; 
     using (var ms = new MemoryStream()) 
     { 
      var ser = new DataContractSerializer(typeof(T)); 
      ser.WriteObject(ms, type); 
      ms.Position = 0; 
      var sr = new StreamReader(ms); 
      s = sr.ReadToEnd(); 
     } 
     using (var xml = new XmlTextReader(s, XmlNodeType.Element, null)) 
     { 
      xml.MoveToContent(); 
      xml.Read(); 
      return xml.Value; 
     } 
    } 
+1

I jak już tej opcji, ponieważ rozciąga ENUM: http: // stackoverflow. com/a/4367868/1243316 –

Odpowiedz

26

Oto moja propozycja - należy przez to daje wyobrażenie o tym, jak to zrobić (sprawdzić również Getting attributes of Enum's value):

public static string ToEnumString<T>(T type) 
{ 
    var enumType = typeof (T); 
    var name = Enum.GetName(enumType, type); 
    var enumMemberAttribute = ((EnumMemberAttribute[])enumType.GetField(name).GetCustomAttributes(typeof(EnumMemberAttribute), true)).Single(); 
    return enumMemberAttribute.Value; 
} 

public static T ToEnum<T>(string str) 
{ 
    var enumType = typeof(T); 
    foreach (var name in Enum.GetNames(enumType)) 
    { 
     var enumMemberAttribute = ((EnumMemberAttribute[])enumType.GetField(name).GetCustomAttributes(typeof(EnumMemberAttribute), true)).Single(); 
     if (enumMemberAttribute.Value == str) return (T)Enum.Parse(enumType, name); 
    } 
    //throw exception or whatever handling you want or 
    return default(T); 
} 
3

Możesz użyć odbicia, aby uzyskać wartość EnumMemberAttribute.

public static string ToEnumString<T>(T instance) 
{ 
    if (!typeof(T).IsEnum) 
     throw new ArgumentException("instance", "Must be enum type"); 
    string enumString = instance.ToString(); 
    var field = typeof(T).GetField(enumString); 
    if (field != null) // instance can be a number that was cast to T, instead of a named value, or could be a combination of flags instead of a single value 
    { 
     var attr = (EnumMemberAttribute)field.GetCustomAttributes(typeof(EnumMemberAttribute), false).SingleOrDefault(); 
     if (attr != null) // if there's no EnumMember attr, use the default value 
      enumString = attr.Value; 
    } 
    return enumString; 
} 

W zależności od tego, jak twoje prace ToEnum, można użyć tego rodzaju podejście również tam. Ponadto typ można wywnioskować, wywołując ToEnumString, np. SerializerHelper.ToEnumString(status);