我如何打开一个设置了 flags 属性的枚举(或者更准确地说是用于位操作)?
我希望能够在与声明的值匹配的开关中命中所有情况。
问题是,如果我有以下枚举
[Flags()]public enum CheckType
{
Form = 1,
QueryString = 2,
TempData = 4,
}
我想使用这样的开关
switch(theCheckType)
{
case CheckType.Form:
DoSomething(/*Some type of collection is passed */);
break;
case CheckType.QueryString:
DoSomethingElse(/*Some other type of collection is passed */);
break;
case CheckType.TempData
DoWhatever(/*Some different type of collection is passed */);
break;
}
如果“theCheckType”同时设置为 CheckType.Form | CheckType.TempData 我希望它同时满足两种情况。显然,由于中断,它不会在我的示例中同时命中,但除此之外它也会失败,因为 CheckType.Form 不等于 CheckType.Form | CheckType.TempData
那么,我可以看到的唯一解决方案是为枚举值的每种可能组合提供一个案例?
就像是
case CheckType.Form | CheckType.TempData:
DoSomething(/*Some type of collection is passed */);
DoWhatever(/*Some different type of collection is passed */);
break;
case CheckType.Form | CheckType.TempData | CheckType.QueryString:
DoSomething(/*Some type of collection is passed */);
DoSomethingElse(/*Some other type of collection is passed */);
break;
... and so on...
但这真的不是很理想(因为它会很快变得很大)
现在我有 3 个 If 条件紧随其后
就像是
if ((_CheckType & CheckType.Form) != 0)
{
DoSomething(/*Some type of collection is passed */);
}
if ((_CheckType & CheckType.TempData) != 0)
{
DoWhatever(/*Some type of collection is passed */);
}
....
但这也意味着,如果我有一个具有 20 个值的枚举,它必须每次都通过 20 个 If 条件,而不是像使用开关时那样“跳转”到仅需要的“case”/。
有没有什么神奇的方法可以解决这个问题?
我已经想到了遍历声明的值然后使用开关的可能性,然后它只会为每个声明的值点击开关,但我不知道它将如何工作以及它的性能是否是一个好主意(与很多 if 相比)?
有没有一种简单的方法可以遍历所有声明的枚举值?
我只能想出使用 ToString() 并用“,”分割,然后遍历数组并解析每个字符串。
更新:
我发现我解释得不够好。我的例子很简单(试图简化我的场景)。
我将它用于 Asp.net MVC 中的 ActionMethodSelectorAttribute 以确定在解析 url/路由时方法是否可用。
我通过在方法上声明这样的东西来做到这一点
[ActionSelectorKeyCondition(CheckType.Form | CheckType.TempData, "SomeKey")]
public ActionResult Index()
{
return View();
}
这意味着它应该检查 Form 或 TempData 是否具有为可用的方法指定的键。
它将调用的方法(我之前的示例中的 doSomething()、doSomethingElse() 和 doWhatever())实际上将 bool 作为返回值,并将使用参数调用(不共享接口的不同集合可以是使用 - 请参阅下面链接中的示例代码等)。
为了希望更好地了解我在做什么,我粘贴了一个简单的例子,说明我在 pastebin 上实际做了什么——可以在这里找到http://pastebin.com/m478cc2b8