按位标志和Switch语句?

时间:2010-10-02 18:19:49

标签: c# enums switch-statement bit-manipulation

我有以下代码(示例),我真的不喜欢这么多'if'检查:

public enum Flags 
{
    p1 = 0x01,  // 0001
    p2 = 0x02,  // 0010  
    p3 = 0x04,  // 0100
    p4 = 0x08   // 1000
};      

public static void MyMethod (Flags flag)
{
    if ((flag & Flags.p1) == Flags.p1)
        DoSomething();

    if ((flag & Flags.p2) == Flags.p2)
        DosomethingElse();

    if ((flag & Flags.p3) == Flags.p3)
        DosomethingElseAgain();

    if ((flag & Flags.p4) == Flags.p4)
        DosomethingElseAgainAndAgain();
}

MyMethod(Flags.p1 | Flags.p3);

有没有办法,我可以使用'switch'语句。也许如果我将它们转换为字符串,或使用数组?

2 个答案:

答案 0 :(得分:8)

这样的东西?

public static void MyMethod(Flags flag)
{
    // Define action-lookup
    var actionsByFlag = new Dictionary<Flags, Action>
    {
        { Flags.p1, DoSomething},
        { Flags.p2, DosomethingElse},
        { Flags.p3, DosomethingElseAgain},
        { Flags.p4, DosomethingElseAgainAndAgain},
    };

    // Find applicable actions
    var actions = actionsByFlag.Where(kvp => (flag & kvp.Key) == kvp.Key)
                               .Select(kvp => kvp.Value);

    //Execute applicable actions
    foreach (var action in actions)
       action();
}

编辑:如果操作顺序很重要,则可能需要OrderBy条款。

答案 1 :(得分:6)

以下是Ani答案的变体:

public static void MyMethod(Flags flag) 
{ 
    // Define action-lookup 
    var dict = new Dictionary<Flags, Action> 
    { 
        { Flags.p1, DoSomething}, 
        { Flags.p2, DosomethingElse}, 
        { Flags.p3, DosomethingElseAgain}, 
        { Flags.p4, DosomethingElseAgainAndAgain}, 
    }; 

    // Find applicable actions 
    var actions = from value in Enum.GetValues(typeof(Flags))
                  where flag.HasFlag(value)
                  select dict[value];

    //Execute applicable actions 
    foreach (var action in actions)
       action(); 
}

这里的重要区别在于它迭代枚举中定义的值而不是字典中的条目。这样,如果向枚举添加新标志而不将其添加到字典中,则在尝试使用新标志时会出现异常。它总是按标志的顺序迭代。