Enum flag attribute C#
本问题已经有最佳答案,请猛点这里访问。
我找了一些相同的话题,但找不到我要找的。我应该使用flag enum flag attribute并检查我的数据是否在此枚举的集合中例如,枚举:
1 2 3 4 5 6 7 8 9 10 11 12 13 | [Flags] private enum MyEnum { Apple, Orange, Tomato, Potato Melon, Watermelon, Fruit = Apple | Orange, Vegetable = Tomato | Potato, Berry = Melon | Watermelon, } |
在这个方法中,我应该检查输入数据。我该怎么做?
1 2 3 4 5 | 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"); } |
什么应该代替"包含数据"?
更新
1 2 3 | private void ZZZ(){ Cheching("Apple"); } |
首先,您需要使用-2的幂序列手动对值进行编号:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [Flags] private enum MyEnum { None = 0, // often useful Apple = 1, Orange = 2, Tomato = 4, Potato = 8, Melon = 16, Watermelon = 32, Fruit = Apple | Orange, Vegetable = Tomato | Potato, Berry = Melon | Watermelon, } |
要检查字符串是否与您的值匹配,您必须首先将其设置为枚举:
1 2 3 4 5 6 7 | private void Checking(string data) { MyEnum v = (MyEnum) Enum.Parse(typeof(MyEnum), data); if((MyEnum.Fruit & v) != 0) MessageBox.Show("It's a Fruit"); ... } |
但是请注意,这样的枚举和字符串与
您还可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [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, } |
然后,为了检查,可以使用以下方法,该方法适用于枚举的所有组成部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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以更短的方式编写它:
1 2 3 4 5 |
这将得到一个包含结果的
除了Henk Holterman的解决方案,您还可以使用扩展方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | [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"); } |
正如@henk holterman所建议的,您需要首先为枚举赋值。所有值应为2的幂(并避免使用0,除非"无"的特殊情况)它应该是这样的:
1 2 | MyEnum eVal= (MyEnum ) Enum.Parse( typeof(MyEnum), data, true ); if((MyEnum.Fruit & eVal) != 0) MessageBox.Show("Fruit"); |
您可能想阅读更多关于位代数和布尔代数的内容。