【发布时间】:2014-07-30 13:01:28
【问题描述】:
我有一组常量,我在我的 C# 项目中使用枚举。在某些情况下,我只需要一个值,而在其他情况下,我需要多个值。我开始使用 IEnumerable 或我的枚举类型的简单数组来处理多个值。但是,我最近开始需要在属性构造函数中为多个属性添加多个值,我想将这些值放入类的 const 字段中。
一个简单的例子:
public enum Browsers {
Firefox, Chrome, IE, Opera, Safari
}
public class SomeClass {
[Attr(new Browsers[] { Browsers.Firefox, Browsers.Chrome })]
public void SomeMethod() { }
[Attr(new Browsers[] { Browsers.Firefox, Browsers.Chrome })]
public void SomeOtherMethod() { }
}
我想将浏览器数组重构为类中的一个字段,但是对于要在属性构造函数中使用的字段,它必须是 const 字段,并且具有数组初始化的字段不能是 const。
然后我尝试在我的枚举上使用 FlagsAttribute,以便枚举可以包含多个值。然后我可以创建一个字段private const Browsers = Browsers.Firefox | Browsers.Chrome,我很好。在这个情况下。
在我只需要一个值的情况下,应用 FlagsAttribute 从而允许多个值并不是那么好。在这些情况下,我总是必须首先检查枚举是否只有一个值(我通过检查它是否是 2 的幂来做到这一点)。我觉得这有点烦人。以一种情况下的可维护性换取其他情况下的较低可维护性 - 不理想。
所以我的问题是有什么聪明的方法可以解决这个问题吗?我想制作两个单独的枚举,一个带有 FlagsAttribute,一个没有,但是我将不得不在两个地方而不是一个地方维护枚举的所有值。同样不理想。
我是否错过了一些可以在不牺牲任何地方的可维护性的方式解决这个问题的方法?
更新: 我希望我的代码看起来像这样:
public class SomeClass {
private const Browsers[] browsers = new Browsers[] { Browsers.Firefox, Browsers.Chrome };
[Attr(browsers)]
public void SomeMethod() { }
[Attr(browsers)]
public void SomeOtherMethod() { }
}
但是这会导致编译错误。
我仅使用单个值的枚举的示例:
public void SomeMethod(Browsers browser) {
/* When using Flags I need to verify that browser contains only a single value */
switch(browser)
{
case Browsers.Firefox:
/* do something */
break;
case Browsers.Chrome:
/* do something */
break;
/* cases for the rest of the values */
}
}
我的问题是:我能否以某种方式创建两个具有相同值的枚举,其中一个具有 Flags 属性而另一个没有?
额外问题:有没有更聪明的方法解决这个问题,我只是没有看到?
【问题讨论】:
-
请记住,始终可以将枚举的基础类型的任何值强制转换为枚举值 - 因此,如果您只希望提供单个值,您仍然需要在某些情况下验证接收到的值方式 - 你不能保证它只会匹配枚举中的值。
-
@AdrianoRepetti - 我做了,作为我的帖子详细信息:)
-
@Damien_The_Unbeliever - 感谢您提醒我这一点。检查 2 的幂可能是最好的方法。
-
您可以使用扩展方法来稍微简化问题。
-
@Silwing - 实际上,使用
Enum.IsDefined可能对您很有效 - 它被定义为对标志的按位组合返回 false,并且仅在枚举为标志时返回单个选项的 true。