打开枚举(带有标志属性)而不声明所有可能的组合?

Switch on Enum (with Flags attribute) without declaring every possible combination?(打开枚举(带有标志属性)而不声明所有可能的组合?)

本文介绍了打开枚举(带有标志属性)而不声明所有可能的组合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何打开一个设置了 flags 属性的枚举(或者更准确地说是用于位操作)?

how do i switch on an enum which have the flags attribute set (or more precisely is used for bit operations) ?

我希望能够在与声明的值匹配的开关中命中所有情况.

I want to be able to hit all cases in a switch that matches the values declared.

问题是,如果我有以下枚举

The problem is that if i have the following enum

[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

If "theCheckType" is set to both CheckType.Form | CheckType.TempData I want it to hit both case's. Obviously it wont hit both in my example because of the break, but other than that it also fails because CheckType.Form is not equal to CheckType.Form | CheckType.TempData

我所看到的唯一解决方案是为枚举值的每个可能组合提供一个案例?

The only solution then as I can see it is to make a case for every possible combination of the enum values ?

类似

    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...

但这真的不是很理想(因为它会很快变得很大)

But that really isnt very desired (as it will quickly grow very big)

现在我有 3 个 If 条件紧随其后

Right now i have 3 If conditions right after eachother instead

有点像

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"/.

But that also means that if i have an enum with 20 values it have to go through 20 If conditions every single time instead of "jumping" to only the needed "case"/'s as when using a switch.

有什么神奇的方法可以解决这个问题吗?

Is there some magic solution to solve this problem?

我想到了循环遍历声明的值然后使用开关的可能性,然后它只会为每个声明的值点击开关,但我不知道它是如何工作的,如果它的性能问题是好主意(与许多 if 相比)?

I have thought of the possibility to loop through the declared values and then use the switch, then it would only hit the switch for each value declared, but I don't know how it will work and if it performance vice is a good idea (compared to a lot of if's) ?

有没有一种简单的方法可以循环遍历所有声明的枚举值?

Is there an easy way to loop through all the enum values declared ?

我只能想出使用 ToString() 并用 "," 分割,然后遍历数组并解析每个字符串.

I can only come up with using ToString() and splitting by "," and then loop through the array and parse every single string.

更新:

我发现我的解释工作做得不够好.我的例子很简单(试图简化我的场景).

I see that i haven't done a good enough job explaining. My example is to simple (tried to simplify my scenario).

我将它用于 Asp.net MVC 中的 ActionMethodSelectorAttribute 以确定在解析 url/路由时方法是否可用.

I use it for a ActionMethodSelectorAttribute in Asp.net MVC to determine if a method should be available when resolving the url/route.

我通过在方法上声明这样的东西来做到这一点

I do it by declaring something like this on the method

[ActionSelectorKeyCondition(CheckType.Form | CheckType.TempData, "SomeKey")]
public ActionResult Index()
{
    return View();
} 

这意味着它应该检查 Form 或 TempData 是否具有为可用方法指定的键.

That would mean that it should check if the Form or TempData have a key as specified for the method to be available.

它将调用的方法(我之前的示例中的 doSomething()、doSomethingElse() 和 doWhatever())实际上将 bool 作为返回值,并将使用参数调用(不共享接口的不同集合可以使用 - 请参阅下面链接中的示例代码等).

The methods it will be calling (doSomething(), doSomethingElse() and doWhatever() in my previous example) will actually have bool as return value and will be called with a parameter (different collections that doesn't share a interface that can be used - see my example code in the link below etc).

希望能更好地了解我在做什么,我粘贴了一个简单的示例,说明我在 pastebin 上实际执行的操作 - 可以在此处找到 http://pastebin.com/m478cc2b8

To hopefully give a better idea of what i am doing i have pasted a simple example of what i am actually doing on pastebin - it can be found here http://pastebin.com/m478cc2b8

推荐答案

这个怎么样.当然,DoSomething 的参数和返回类型等,可以是任何你喜欢的.

How about this. Of course the arguments and return types of DoSomething, etc., can be anything you like.

class Program
{
    [Flags]
    public enum CheckType
    {
        Form = 1,
        QueryString = 2,
        TempData = 4,
    }

    private static bool DoSomething(IEnumerable cln)
    {
        Console.WriteLine("DoSomething");
        return true;
    }

    private static bool DoSomethingElse(IEnumerable cln)
    {
        Console.WriteLine("DoSomethingElse");
        return true;
    }

    private static bool DoWhatever(IEnumerable cln)
    {
        Console.WriteLine("DoWhatever");
        return true;
    }

    static void Main(string[] args)
    {
        var theCheckType = CheckType.QueryString | CheckType.TempData;
        var checkTypeValues = Enum.GetValues(typeof(CheckType));
        foreach (CheckType value in checkTypeValues)
        {
            if ((theCheckType & value) == value)
            {
                switch (value)
                {
                    case CheckType.Form:
                        DoSomething(null);
                        break;
                    case CheckType.QueryString:
                        DoSomethingElse(null);
                        break;
                    case CheckType.TempData:
                        DoWhatever(null);
                        break;
                }
            }
        }
    }
}

这篇关于打开枚举(带有标志属性)而不声明所有可能的组合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:打开枚举(带有标志属性)而不声明所有可能的组合?

基础教程推荐