2010-10-02 41 views
6

Aşağıdaki kodu (örnek) var ve ben gerçekten 'eğer' bu kadar çok çekleri ile rahat değilim:Bitsel bayraklar ve Anahtar ifadesi?

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

i bir 'anahtar' deyimi kullanabileceği bazı yolu var mı. Belki onları dizilere dönüştürürsem ya da diziler kullanırsam?

+2

A 'switch' ifadesi ne istediğinizi değil, çünkü eğer bir sürü gruba eşdeğerse… eğer… else…… ifadeleri, açıkça sahip olduğunuz şey değil. – Gabe

+5

Not: C# 4.0'da 'flag.HasFlag (Flags.p1)' yerine 'flag & flags.p1 == Flags.p1' 'yi kullanabilirsiniz. – Gabe

+0

@Gabe: hivemind! –

cevap

7

Böyle bir şey mi var?

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

DÜZENLEME: eylemlerin sırası önemliyse, bir OrderBy fıkra gerekebilir.

+6

C# 4.0'da 'dict.Where öğesini kullanabilirsiniz (kv => flag.HasFlag (kv.Key))' –

+0

@Ani, Dictionary ve LINQ. Yeni C# 4.0 özelliğinden bahsetmek için @Gabe ve @Callum Rogers'a teşekkürler. – kofucii

+0

İyi yanıt, ancak yöntem * dışında eylem araması * tanımlayın. –

6

İşte Ani 'ın Yanıta varyasyonu olan:

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

Burada önemli fark oldukça sözlükte girdileri daha numaralandırma tanımlanan değerler üzerinde dolaşır olmasıdır. Bu şekilde, sözlüğe eklemeden enum'a yeni bir bayrak eklerseniz, yeni bayrağı kullanmaya çalıştığınızda bir istisna alırsınız. Ve her zaman bayrakların sırasına göre yinelenir.