2014-10-01 2 views
7

У меня есть класс «лицензия», которая представляет собой набор кучу перечислений флагов, как это:Пытаясь разобрать перечисление флаг в строку

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

Дело в том, что различные флаги той же категории могут быть OR'd вместе, чтобы сформировать профиль того, что пользователь может сделать с указанной лицензией. Теперь я пытаюсь показать значения «Использование» и «Платформа» в удобном для человека образом, например, если Usage == UsageType.read | UsageType.write, тогда он должен быть проанализирован как «читать, писать».

Я сделал это успешно с одним типом перечисления, проверив значение для каждого флага и добавляя enumitem.ToString() для каждого флага, который он имеет для строки. Поскольку у меня много этих перечислений и значений, я хотел бы предложить более общий подход.

Я придумал это (ниже), но так как я не очень хорошо знаком с шаблонными функциями в C#, так что я не знаю, почему это не работает, но по крайней мере он должен показать, что я имею в виду:

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

Это говорит о том, что T не содержит определения для «HasFlag», но как это могло быть теперь, если он не знает, что такое T?

+0

Не совсем дубликат, но проблема Вы сталкиваетесь в основном это: http://stackoverflow.com/questions/79126/create-generic-method-constraining-t-to-an-enum. Решение, предоставленное этому вопросу, должно помочь вам, где вам нужно. –

+0

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

+0

Вы пробовали 'enumValue.ToString()'? – jrummell

ответ

25

Вы должны использовать FlagsAttribute, что заставляет встроенные методы ToString и Enum.Parse работать так, как вы хотите. Также обратите внимание, что соглашение состоит в том, что флаги перечислены именами should be plural, так, например, UsageTypes вместо 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

Говоря о соглашениях об именах, поля перечисления [должны быть в случае Паскаля] (https://msdn.microsoft.com/en-us/library/ms229043). – Shimmy