2014-10-01 17 views
7

Mam klasy „licencję”, która jest zbiorem bandą flagi enum tak:Próbując analizować flagi enum ciąg

Public class License 
{ 
    UsageType Usage { get; set; } 
    PlatformType Platform { get; set; } 

    public enum UsageType { read = 1, write = 2, wipe = 4, all = 7 } 
    public enum PlatformType { windows = 1, linux = 2, ios = 4, all = 7 } 

    etc... 
} 

Chodzi o to, że różne flagi tej samej kategorii można być razem, aby utworzyć profil tego, co użytkownik może zrobić ze wspomnianą licencją. Teraz próbuję wyświetlać wartości "użytkowania" i "platformy" w przyjazny dla człowieka sposób, na przykład, jeśli użycie == usageType.read | UsageType.write, a następnie powinno być przetwarzane na "czytaj, pisz".

Zrobiłem to z powodzeniem za pomocą jednego typu wyliczeniowego, testując wartość dla każdej flagi i dołączając enumitem.ToString() dla każdej flagi, która ma na łańcuch. Ponieważ mam dużo tych wyrażeń i wartości, chciałbym wymyślić bardziej ogólne podejście.

wymyśliłem to (poniżej), ale ponieważ nie jestem bardzo obeznany z funkcji szablonów w C#, więc nie wiem, dlaczego to nie działa, ale przynajmniej powinien zilustrować, co mam na myśli:

private string parseEnum<T>(T value) 
{ 
    string ret = ""; 
    foreach (var ei in (T[])Enum.GetValues(typeof(T))) 
    { 
     if (value.HasFlag(ei)) ret += ei.ToString() + ", "; 
    } 
    ret = ret.substring(0, ret.Length-1); 
    return ret; 
} 

Mówi się, że T nie zawiera definicji "HasFlag", ale jak to możliwe, że jeśli nie wie, co to jest T?

+0

Niezupełnie duplikat, ale problem, że napotkali jest zasadniczo to: http://stackoverflow.com/questions/79126/create-generic-method-constraining-t-to-an-enum. Rozwiązanie dostarczone na to pytanie powinno Cię doprowadzić tam, gdzie musisz. –

+0

http://msdn.microsoft.com/en-us/library/system.flagsattribute(vsv1.110).aspx lub http://stackoverflow.com/questions/8447/what-does-the-flags- enum-attribute-mean-in-c – Mephy

+0

Czy próbowałeś 'enumValue.ToString()'? – jrummell

Odpowiedz

25

Powinieneś użyć , co powoduje, że wbudowane metody ToString i Enum.Parse działają tak, jak chcesz. Zwróć też uwagę, że konwencja jest taka, że ​​flagi wyliczają nazwy should be plural, np. UsageTypes zamiast UsageType.

[Flags] 
public enum UsageTypes { Read = 1, Write = 2, Wipe = 4, All = 7 } 
[Flags] 
public enum PlatformTypes { Windows = 1, Linux = 2, iOs = 4, All = 7 } 

var e1 = License.UsageTypes.Read | License.UsageTypes.Write; 
var s = e1.ToString(); 
Debug.Assert(s == "Read, Write"); 
var e2 = (License.UsageTypes)Enum.Parse(typeof(License.UsageTypes), s); 
Debug.Assert(e1 == e2); 
+1

Mówiąc o konwencjach nazewnictwa, polach wyliczeniowych [powinno być w przypadku Pascala] (https://msdn.microsoft.com/en-us/library/ms229043). – Shimmy