2014-10-01 10 views
7

Ho una classe "licenza", che è una raccolta di un mazzo di bandiere enum come questo:Cercando di analizzare un enum bandiera per stringa

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... 
} 

Il punto è che le varie bandiere della stessa categoria può essere OR insieme per formare un profilo di ciò che l'utente può fare con detta licenza. Ora sto cercando di visualizzare i valori di "Uso" e "Piattaforma" in un modo umano-amichevole, ad esempio, se Usage == UsageType.read | UsageType.write quindi dovrebbe essere analizzato in "read, write".

L'ho eseguito correttamente con un singolo tipo enum testando il valore per ogni flag e aggiungendo enumitem.ToString() per ogni flag che ha su una stringa. Dal momento che ho un sacco di questi enumeri e valori, mi piacerebbe venire con un approccio più generico.

sono arrivato fino a questo (sotto), ma siccome io non sono molto familiare con funzioni template in C# in modo da non so il motivo per cui questo non funziona, ma almeno dovrebbe illustrare cosa intendo:

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; 
} 

Sta dicendo che T non contiene una definizione per "HasFlag" ma come potrebbe ora che se non sa cosa sia T?

+0

Non esattamente un duplicato, ma il problema incontrato è essenzialmente questo: http://stackoverflow.com/questions/79126/create-generic-method-constraining-t-to-an-enum. La soluzione fornita a questa domanda dovrebbe portarti dove devi essere. –

+0

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

+0

Hai provato 'enumValue.ToString()'? – jrummell

risposta

25

È necessario utilizzare FlagsAttribute, che fa sì che i metodi integrati ToString e Enum.Parse funzionino nel modo desiderato. Si noti inoltre che la convenzione è che i nomi delle enumerazioni delle bandiere sono should be plural, quindi ad es. UsageTypes anziché 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

Parlando di convenzioni di denominazione, campi enum [dovrebbe essere in caso Pascal] (https://msdn.microsoft.com/en-us/library/ms229043). – Shimmy

Problemi correlati