2013-08-01 9 views
6

Jeśli mam enumSprawdź, czy enum jest w jednym z pożądanych stanów

[Flags] 
    public enum GameFlow 
    { 
     Normal = 1, 
     NormalNoMove = 2, 
     Paused = 4, 
     Battle = 8 
    } 

Czy to możliwe, aby sprawdzić, czy enum jest w jednej z pożądanych stanów za pomocą jednego czeku? Na przykład, jeśli chciałbym sprawdzić, czy enum to Normal czy NormalNoMove, czy zawsze muszę to napisać w ten sposób?

if(Flow == GameFlow.Normal || Flow == GameFlow.NormalNoMove) 

Nie jest to duży problem, jeśli istnieją tylko dwie wartości, ale nie będzie więcej stanów enum i byłoby miło, gdybym tylko musiał zmienić go w jednym miejscu. Czy można w jakiś sposób utworzyć alias enum, który zwróciłby wartość true, gdyby wartość wyliczeniowa była równa Normal lub NormalNoMove? Czy muszę napisać jakąś metodę pomocnika, aby to osiągnąć (metoda rozszerzenia?)

+0

Przypuszczam, że Flow jest typu GameFlow? –

+0

Tak, jest to typ GameFlow: – kasztelan

Odpowiedz

7

Logika bitowa powinna działać na podstawie znaczników flagi w ten sposób.

if((Flow & (GameFlow.Normal | GameFlow.NormalNoMove)) > 0) 

Możliwe jest również, aby tworzyć wartości enum, które łączą inne wartości, jak wspominam here.

Więc w twoim przypadku:

[Flags] 
public enum GameFlow 
{ 
    Normal = 1, 
    NormalNoMove = 2, 
    Paused = 4, 
    Battle = 8, 
    AnyNormal = Normal | NormalNoMove 
} 

bool IsNormal(GameFlow flow) 
{ 
    return (flow & GameFlow.AnyNormal) > 0; 
} 

a test LINQPad:

void Main() 
{ 
    IsNormal(GameFlow.Normal).Dump();// True 
    IsNormal(GameFlow.NormalNoMove).Dump();// True 
    IsNormal(GameFlow.Paused).Dump();// False 
    IsNormal(GameFlow.Battle).Dump();// False 

    IsNormal(GameFlow.Normal | GameFlow.Paused).Dump();// True 
    IsNormal(GameFlow.NormalNoMove | GameFlow.Battle).Dump();// True 
    IsNormal(GameFlow.Paused | GameFlow.Battle).Dump();// False 
    IsNormal(GameFlow.Battle | GameFlow.Normal).Dump();// True 

} 

podstawie Twojego komentarza, zastanawiam się, czy należy skorygować bitowe flagi tutaj też. Wygląda na to, że "Normalny" to stan, który chcesz sprawdzić, i "NormalNoMove" na tym opiera się. Może twój enum powinien wyglądać mniej więcej tak:

[Flags] 
public enum GameFlow 
{ 
    Normal = 1, 
    NormalNoMove = Normal | 2, 
    Paused = 4, 
    Battle = 8 
} 

W ten sposób można sprawdzić, czy flow & GameFlow.Normal > 0 aby sprawdzić, czy jesteś w obu normalnego stanu: NormalNoMove prostu „rozciąga” Normal, że tak powiem.

+0

Tak, wiem o tym, ale nadal muszę wyraźnie używać Normal i NormalNoMove w każdym miejscu, w którym sprawdzam stan. Miałem nadzieję, że istnieje sposób na stworzenie kolejnego stanu wyliczeniowego, na przykład NormalState, który zwróciłby wartość true w sprawdzeniu warunków, gdyby wartość była Normalna lub NormalnaNoMove – kasztelan

+0

@kasztelan: Rozszerzyłem moją odpowiedź, aby zaadresować twój komentarz. – StriplingWarrior

+0

Dziękujemy! '(flow & GameFlow.AnyNormal)> 0;' jest odpowiedzią, której szukałem. W ten sposób, jeśli kiedykolwiek będę chciał rozszerzyć AnyNormal o trzecie państwo, będę musiał zmienić jego deklarację w wyliczeniu. Idealny! – kasztelan

1

podstawie komentarzu do użytkownika @ StringlingWarrior odpowiedź, można po prostu utworzyć metodę rozszerzenia, które skrócą swój kod:

public static class GameFlowExtensions 
{ 
    public static bool IsNormal(this GameFlow flow) 
    { 
     return (flow & (GameFlow.Normal | GameFlow.NormalNoMove)) > 0; 
    } 
} 

// usage: 
if (Flow.IsNormal()) 
+0

Dziękuję, ale na szczęście nie muszę tworzyć metody rozszerzania, część' (flow & GameFlow.AnyNormal)> 0; 'była dokładnie tym, czego szukałem – kasztelan

1

można ustawić zmienną być równa GameFlow.Normal i GameFlow.NormalNoMove a następnie porównać wartość musisz to zrobić, tak:

GameFlow NormalOrNormalNoMove = GameFlow.Normal | GameFlow.NormalNoMove; 
... 
if ((Flow & NormalOrNormalNoMove) > 0) 
{ 
    // Your code 
}