【问题标题】:Loop through "selected" Enum values? [duplicate]循环“选定”枚举值? [复制]
【发布时间】:2012-04-24 17:56:25
【问题描述】:

我知道如何遍历枚举属性列表,但我将如何遍历所有“选定”枚举属性?例如,如果有人用Prop1 | Prop2 对抗public enum Foo { Prop1; Prop2; Prop3 },我将如何做到这一点?

这就是我现在拥有的:

var values = Enum.GetValues(typeof(FileStatus)).Cast<FileStatus>();
foreach (var value in values)
{
}

它循环遍历所有枚举属性,但我想只循环“选择”的那些。

更新:[Flags] 属性已设置。

更新 2:枚举包含大量属性,我不能也不会键入/硬编码单个属性检查,而是想动态循环遍历每个属性并检查我的枚举实例 Bar包含循环项集。

【问题讨论】:

  • 你把 FlagsAttribute 贴在枚举上了吗?
  • @Hexxagonal:没关系。但是,显式赋值非常重要。
  • @Hexxagonal 这真的比任何事情都更可选。枚举可能是也可能不是两个的幂。标志是否ATT。设置应该很重要,但实际上并不重要。
  • 这个问题正在Meta讨论。

标签: c#


【解决方案1】:

以下内容如何:

FileStatus status = FileStatus.New|FileStatus.Amazing;

foreach (FileStatus x in Enum.GetValues(typeof(FileStatus)))
{
    if (status.HasFlag(x)) Console.WriteLine("{0} set", x);
}

或者一举 LINQ:

var flags = Enum.GetValues(typeof(FileStatus))
                .Cast<FileStatus>()
                .Where(s => status.HasFlag(s));

【讨论】:

  • +1,我同意,只有设置了标志才会打印。
  • 效果很好! if 仅在为状态设置循环枚举属性时通过!
【解决方案2】:
[Flags]
public enum Foo
{
    Prop1 = 1,
    Prop2 = 1 << 1,
    Prop3 = 1 << 2
}

public static class FooExtensions
{
    private static readonly Foo[] values = (Foo[])Enum.GetValues(typeof(Foo));

    public static IEnumerable<Foo> GetComponents(this Foo value)
    {
        return values.Where(v => (v & value) != 0);
    }
}

public static class Program
{
    public static void Main(string[] args)
    {
        var foo = Foo.Prop1 | Foo.Prop3;

        var components = foo.GetComponents().ToArray();
    }
}

【讨论】:

    【解决方案3】:

    假设您将此设置为位掩码,则只需“与”值即可确定选择哪些值。

     SomeEnum bitmask = value;
    
     if(bitmask & SomeEnum.Value1 > 0)
        // SomeEnum.Value1 was set
    

    【讨论】:

    • bitmask.HasFlag(SomeEnum.Value1) 更具可读性并且做同样的事情
    • 好点!尽管如此,为了完整起见,很高兴能准确地了解它在幕后所做的事情。
    【解决方案4】:
    FileStatus someValue = ...;
    var selectedValues = new List<FileStatus>();
    var allValues = Enum.GetValues(typeof(FileStatus)).Cast<FileStatus>();
    foreach (var value in allValues )
    {
      if(someValue & value != 0)//note bitwise AND, not logical AND.
      {
         selectedValues.Add(value);
         //this value is selected.  You can stick it in a List or do whatever with it.
      }
    }
    

    【讨论】:

      【解决方案5】:

      您需要使用Flags 属性标记枚举。要获取值可以使用yourObject.EnumProperty.HasFlag 方法,例如:

      class Program 
      {
          [Flags]
          public enum Bar { Prop1, Prop2, Prop3 }
      
          public class Foo
          {
              public Bar SelectedBar { get; set; }
          }
      
          static void Main(string[] args)
          {
              var foo = new Foo();
              foo.SelectedBar = Bar.Prop1 | Bar.Prop2;
      
              foo.SelectedBar.HasFlag(Bar.Prop1); //true
              foo.SelectedBar.HasFlag(Bar.Prop2); //true
              foo.SelectedBar.HasFlag(Bar.Prop3); //false
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-15
        • 1970-01-01
        • 2012-01-30
        • 1970-01-01
        • 2013-05-16
        • 2015-01-09
        • 1970-01-01
        相关资源
        最近更新 更多