繁体   English   中英

将标志枚举用作普通枚举

[英]Use Flags Enum as a normal Enum

有没有一种方法可以选择性地将[Flags]枚举强制为“ Flags”以用于特定用途?

例如说我有

enum MyEnum {
     X ,
     Y , 
     Z 
 }

现在假设我有两个班级AB B类将主要在IEnumerable<B> 类A负责解析此列表,但仅在枚举匹配特定值时;

 class B {
      MyEnum MyProperty { get; set; }
  }

 class A {
      MyEnum Target = MyEnum.C;
      void DoSomething(IEnumerable<B> list) {

           for (var b in list) {
               if (b.MyProperty == this.Target) {
                   // Do Some Work
               }
           }
      }
 }

现在假设我希望类A能够与多种类型的B一起使用。我可以将[F​​lags]属性添加到我的枚举中,并执行以下操作:

[Flags]
enum MyEnum {
     None = 0,
     X = 1,
     Y = 2, 
     Z = 4
 }


 class B {
      MyEnum MyProperty { get; set; }
  }

 class A {
      MyEnum Target = MyEnum.X | MyEnum.Z;
      void DoSomething(IEnumerable<B> list) {

           for (var b in list) {
               if (this.Target.HasFlag(b.MyProperty)) {
                   // Do Some Work
               }
           }
      }
 }

但是,现在可以将类B的MyProperty用作标志,这是一个问题,因为没有MyEnum.X | MyEnum.Y MyEnum.X | MyEnum.Y中的B.MyProperty A之内有意义是因为我针对的是各种B类。

我提出的解决方法是:

enum MyEnum {
     None = 0,
     X = 1,
     Y = 2, 
     Z = 4
 }

[Flags]
enum MyEnumTarget {
     None = 0,
     X = 1,
     Y = 2, 
     Z = 4
 }

 class B {
      MyEnum MyProperty { get; set; }
  }

 class A {
      MyEnumTarget Target = MyEnumTarget.X | MyEnumTarget.Z;
      void DoSomething(IEnumerable<B> list) {

           for (var b in list) {
               if (this.Target.HasFlag((MyEnumTarget)b.MyProperty)) {
                   // Do Some Work
               }
           }
      }
 }

虽然这有效,但绝对是一团糟。 我现在必须跟踪两个不同的枚举。 我对一个进行任何更改,我必须对另一个进行更改,并且必须确保值已同步。 最重要的是,我现在必须转换为MyEnumTarget才能将值传递给Enum.HasFlag 当然,我可以进行按位操作,但意图并不总是那么明显。 无论哪种方式,我仍然需要两个“匹配”的枚举。

有没有更好的办法做到这一点? 是否有某种方式使用单个枚举类型,并迫使某种[NoFlags]属性上B.MyProperty 还是让两个枚举被认为是最佳方法/最佳实践?

如果重要,我正在使用C#6.0

从根本上说,无论是设计成具有每个枚举类型是位掩码,或者不是。 您可能会考虑的选项:

  • 根据您的代码两个独立的枚举
  • 一个非标志枚举,但将A.Property List<MyEnum>或类似名称
  • 一个标志枚举,但使B.Property设置程序验证仅设置了一个位,否则抛出ArgumentException

两种用途有什么不同? 听起来这应该是两个不同的枚举,因为它们的含义不同。 它们的使用合同不同。 如果这些是类,我建议您应用接口隔离原则 ,因为不同的客户端以不同的方式使用它们。

由于这些是枚举,因此可以将它们包装在具有接口隔离​​的类中,或者至少区分两个枚举。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM