接通枚举(带标志属性)不宣每一种可能的组合? [英] Switch on Enum (with Flags attribute) without declaring every possible combination?

查看:105
本文介绍了接通枚举(带标志属性)不宣每一种可能的组合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎么打开具有标志属性集(或更多precisly用于位运算)枚举?



我希望能够全部命中案件在该声明的价值相匹配的开关。



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

  [旗()]公共枚举CheckType 
{
组成= 1,
查询字符串= 2,
的TempData = 4,
}

和我想用这样的


$ b $开关b

 开关(theCheckType)
{
情况下C​​heckType.Form:
DoSomething的(/ *某些类型的集合传递* /);
中断;

情况下CheckType.QueryString:
DoSomethingElse(/ *一些其他类型的集合传递* /);
中断;

情况下CheckType.TempData
DoWhatever(/ *一些不同类型的集合传递* /);
中断;
}

如果theCheckType被设置为既CheckType.Form | CheckType.TempData我希望它击中两个案例的。显然,它不会在我,因为休息的例子都命中,但除此之外,它也失败,因为CheckType.Form不等于CheckType.Form | CheckType.TempData



那么唯一的解决方案,我可以看到它是充分的理由枚举值的每一个可能的组合?



类似

 情况下CheckType.Form | CheckType.TempData:
DoSomething的(/ *某些类型的集合传递* /);
DoWhatever(/ *一些不同类型的集合传递* /);
中断;

的情况下CheckType.Form | CheckType.TempData | CheckType.QueryString:
DoSomething的(/ *某些类型的集合传递* /);
DoSomethingElse(/ *一些其他类型的集合传递* /);
中断;

...等等...



但是,真正地不是非常需要的(因为它很快就会变得非常大)



现在,我有3个。如果条件合适的后海誓山盟,而不是



类似

  IF((_CheckType&安培;!CheckType.Form)= 0)
{
DoSomething的(/ *某些类型的集合传递* /);
}

如果((_CheckType&安培; CheckType.TempData)!= 0)
{
DoWhatever(/ *某些类型的集合传递* /);
}

....



但是,这也意味着如果我有20个值枚举它要经过20如有条件,每一次,而不是使用一个开关时,跳楼,只为需要的案例/人的作为。



有一些神奇的解决方案来解决这个问题?



我已经通过声明价值思想的可能性循环,然后使用开关,然后它会只打了声明的每个值开关,但我不知道它是如何工作的,如果它的性能副是一个好主意(相比有很多的,如果的)?



时有过声明的所有枚举值的简单方法循环?



我只能想出了使用toString()和分裂的,然后循环。通过阵列和分析每一个字符串






更新:



我看到,我还没有做得足够好的工作地名释义。
我的例子是简单(试图简化我的情况)。



我用它在Asp.net MVC中的ActionMethodSelectorAttribute,以确定是否一个方法应该是可当解析URL /路由。



我用的方法



<$ p $声明是这样做的p> [ActionSelectorKeyCondition(CheckType.Form | CheckType.TempData,SomeKey)]
公众的ActionResult指数()
{
返回查看();
}

这将意味着它应该检查表或TempData的有一个密钥该方法规定为可用。



将被调用的方法(DoSomething的(),doSomethingElse()和doWhatever()在我前面的例子)实际上有BOOL作为返回值,将被用参数(这并不共享可以使用界面不同的集合 - 请参阅下面等的链接我的示例代码)。



要希望给一个什么样的更好的主意我我做我已经贴的什么,我实际上做的引擎收录一个简单的例子 - 它可以在这里找到 http://pastebin.com/m478cc2b8


解决方案

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

 类节目
{
[国旗]
公共枚举CheckType
{
组成= 1,
查询字符串= 2,
的TempData = 4,
}

私人静态布尔DoSomething的(IEnumerable的CLN)
{
Console.WriteLine(DoSomething的);
返回真;
}

私人静态布尔DoSomethingElse(IEnumerable的CLN)
{
Console.WriteLine(DoSomethingElse);
返回真;
}

私人静态布尔DoWhatever(IEnumerable的CLN)
{
Console.WriteLine(DoWhatever);
返回真;
}

静态无效的主要(字串[] args)
{
VAR theCheckType = CheckType.QueryString | CheckType.TempData;
VAR checkTypeValues = Enum.GetValues(typeof运算(CheckType));
的foreach(在checkTypeValues CheckType值)
{
如果((theCheckType&安培;价值)==值)
{
开关(值)
{
情况下C​​heckType.Form:
DoSomething的(NULL);
中断;
情况下CheckType.QueryString:
DoSomethingElse(NULL);
中断;
情况下CheckType.TempData:
DoWhatever(NULL);
中断;
}
}
}
}
}


how do i switch on an enum which have the flags attribute set (or more precisly 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,
}

and i want to use a switch like this

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;
}

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 ?

Something like

    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)

Right now i have 3 If conditions right after eachother instead

Something like

if ((_CheckType & CheckType.Form) != 0)
{
    DoSomething(/*Some type of collection is passed */);
}

if ((_CheckType & CheckType.TempData) != 0)
{
    DoWhatever(/*Some type of collection is passed */);
}

....

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 ?

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 dont 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 ?

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


UPDATE:

I see that i havent done a good enough job explaning. My example is to simple (tried to simplify my scenario).

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();
}

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

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 doesnt share a interface that can be used - see my example code in the link below etc).

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

解决方案

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;
                }
            }
        }
    }
}

这篇关于接通枚举(带标志属性)不宣每一种可能的组合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆