Побитовые флаги и оператор Switch? - PullRequest
8 голосов
/ 02 октября 2010

У меня есть следующий код (пример), и мне не очень удобно с таким количеством проверок «если»:

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 ]

8 голосов
/ 02 октября 2010

Как-то так?

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.

6 голосов
/ 02 октября 2010

Вот вариант ответа 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(); 
}

Важным отличием здесь является то, что он перебирает определенные значения в перечислении, а не записи в словаре.Таким образом, если вы добавите новый флаг в перечисление, не добавляя его в словарь, вы получите исключение при попытке использовать новый флаг.И он всегда повторяется в порядке флагов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...