枚举标志属性C#

这个问题在这里已经有了答案:

  • 在C#中,[Flags]枚举属性意味着什么? 10个答案

  • 首先,您需要使用powers-of-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"); 
        ...
    }
    

    但请注意,像这样在Enum和字符串之间交换是有限的, Parse()是有限的。


    除了Henk 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");       
    } 
    

    您也可以使用Enum类的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"

    链接地址: http://www.djcxy.com/p/54427.html

    上一篇: Enum flag attribute C#

    下一篇: Can not cast integer to Enum in Generic method