[英]Use Flags Enum as a normal Enum
有没有一种方法可以选择性地将[Flags]
枚举强制为“ Flags”以用于特定用途?
例如说我有
enum MyEnum {
X ,
Y ,
Z
}
现在假设我有两个班级A
和B
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一起使用。我可以将[Flags]属性添加到我的枚举中,并执行以下操作:
[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.