2013-08-19 172 views
3

我看起來幾個相同的主題,但沒有找到我在找什麼 我應該使用標誌枚舉標誌屬性,並檢查我的數據是否在此枚舉的集合之一 例如,enum:枚舉標誌屬性C#

[Flags] 
private enum MyEnum { 
Apple, 
Orange, 
Tomato, 
Potato 
Melon, 
Watermelon, 

Fruit = Apple | Orange, 
Vegetable = Tomato | Potato, 
Berry = Melon | Watermelon, 
} 

在方法中,我應該檢查一個輸入數據。我該怎麼做?

private void Checking(string data){ 
if(MyEnum.Fruit contains data) MessageBox.Show("Fruit"); 
if(MyEnum.Vegetable contains data) MessageBox.Show("Vegetables"); 
if(MyEnum.Berry contains data) MessageBox.Show("Berry"); 
} 

什麼應該代替「包含數據」?

UPDATE

private void ZZZ(){ 
Cheching("Apple"); 
} 
+2

給我們一個'data'字符串的例子。你必須給你的水果價值等於2:1,2,4,8,16,32的權力,否則它將無法工作。 – xanatos

+0

@Closevoters:最關鍵的詞語「Parse」只在整個頁面上出現一次,在一個無關的評論中。冠軍比賽和一堆選票不會成爲一個好選擇。 –

回答

8

首先,你需要用權力爲2的序列手動編號的值:

[Flags] 
private enum MyEnum 
{ 
    Apple = 1, 
    Orange = 2, 
    Tomato = 4, 
    Potato = 8, 
    Melon = 16, 
    Watermelon = 32, 

    Fruit = Apple | Orange, 
    Vegetable = Tomato | Potato, 
    Berry = Melon | Watermelon, 
} 

[Flags]屬性不是絕對必要的,它只是控制ToString()行爲。

,並檢查一個您是否值匹配,你必須讓它枚舉第一:

private void Checking(string data) 
{ 
    //MyEnum v = (MyEnum) Enum.Parse(data); 
    MyEnum v = (MyEnum) Enum.Parse(typeof(MyEnum), data); 

    if((MyEnum.Fruit & v) != 0) MessageBox.Show("Fruit"); 
    ... 
} 

但是千萬注意,枚舉和字符串之間交換這樣是有限的,Parse()有限。

+0

是的,它幫助了我。謝謝! – Bashnia007

+0

不應該是'Enum.Parse(typeof(MyEnum),data);'? –

+0

@DanielHilgarth - 修復。 –

1

爲@Henk Holterman曾建議,你需要首先分配值枚舉。
所有的值應該是2的冪(避免使用0,除了「無」的特殊情況) 它應該是這個樣子:

MyEnum eVal= (MyEnum) Enum.Parse(typeof(MyEnum), data, true); 
if((MyEnum.Fruit & eVal) != 0) MessageBox.Show("Fruit"); 

你可能想了解更多關於bitwise和布爾代數。

+0

運營商'|'不能應用於'Program.Types'和'string'類型的操作數。 – Bashnia007

+0

@Avi Turner:您需要使用按位AND,而不是按位OR。 –

+0

@DanielHilgarth。我的錯。固定... –

2

除了亨克Holterman的解決方案,您可以使用擴展方法

[Flags] 
private enum MyEnum { 
    None = 0, 
    Apple = 1, 
    Orange = 2, 
    Tomato = 4, 
    Potato = 8, 
    Melon = 16, 
    Watermelon = 32, 

    Berry = Melon | Watermelon, 
    Fruit = Apple | Orange, 
    Vegetable = Potato | Tomato 
} 

private static class MyEnumExtensions { 
    public static Boolean IsFruit(this MyEnum value) { 
    return (value & MyEnum.Fruit) == MyEnum.Fruit; 
    } 

    public static Boolean IsVegetable(this MyEnum value) { 
    return (value & MyEnum.Vegetable) == MyEnum.Vegetable; 
    } 

    public static Boolean IsBerry(this MyEnum value) { 
    return (value & MyEnum.Berry) == MyEnum.Berry; 
    } 
} 

... 

MyEnum data = ... 

if (data.IsBerry()) { 
    MessageBox.Show("Berry");  
} 
2

您還可以使用Enum -class的HasFlag - 方法。正如Henk指出的那樣,需要使用2次冪次序的值手動爲您的枚舉賦值。

[Flags] 
private enum MyEnum 
{ 
    Apple = 1, 
    Orange = 2, 
    Tomato = 4, 
    Potato = 8, 
    Melon 16, 
    Watermelon = 32, 

    Fruit = Apple | Orange, 
    Vegetable = Tomato | Potato, 
    Berry = Melon | Watermelon, 
} 

然後,檢查您可以使用下面的方法,它正在爲您列舉的所有組成部分:

void Cheking(string data) 
{ 
    // Get the enum value of the string passed to the method 
    MyEnum myEnumData; 
    if (Enum.TryParse<MyEnum>(data, out myEnumData)) 
    { 
     // If the string was a valid enum value iterate over all the value of 
     // the underlying enum type 
     var values = Enum.GetValues(typeof(MyEnum)).OfType<MyEnum>(); 
     foreach (var value in values) 
     { 
      // If the value is not a power of 2 it is a composed one. If it furthermore 
      // has the flag passed to the method this is one we searched. 
      var isPowerOfTwo = (value != 0) && ((value & (value - 1)) == 0); 
      if (!isPowerOfTwo && value.HasFlag(myEnumData)) 
      { 
       MessageBox.Show(value.ToString()); 
      } 
     } 
    } 
    // In case an invalid value had been passed to the method 
    // display an error message. 
    else 
    { 
     MessageBox.Show("Invalid Value"); 
    } 
} 

或者用它寫在一個較短的方式LINQ:

var results = Enum.GetValues(typeof(MyEnum)) 
        .OfType<MyEnum>() 
        .Select(x => new { Value = x, IsPowerOfTwo = (x != 0) && ((x & (x - 1)) == 0) }) 
        .Where(x => !x.IsPowerOfTwo && x.Value.HasFlag(myEnumData)) 
        .Select(x => x.Value.ToString()); 

這將給出包含結果的IEnumerable<string>。如果myEnumData的值爲MyEnum.Apple,結果將只包含值"Fruit"

+0

是的,但不是在字符串「蘋果」。 –

+0

@HenkHolterman感謝提示 - 我修正了這個問題。 – Spontifixus