2010-10-02 21 views
6

मैं निम्नलिखित कोड (उदाहरण) है, और मैं वास्तव में इतने सारे 'अगर चेक के साथ सहज नहीं हूँ:बिटवाई झंडे और स्विच स्टेटमेंट?

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

वहाँ कोई रास्ता है कि मैं एक' स्विच 'बयान इस्तेमाल कर सकते हैं है,। शायद अगर मैं उन्हें तारों में परिवर्तित करता हूं, या सरणी का उपयोग करता हूं?

+2

एक 'switch' बयान आप क्या चाहते हैं, क्योंकि यह' अगर ... किसी और यदि किसी और ... अगर ... 'बयान है, जो स्पष्ट रूप से नहीं है तुम्हारे पास क्या है की एक पूरी गुच्छा के बराबर है नहीं है। – Gabe

+5

ध्यान दें कि सी # में 4.0 आप के बजाय 'का झंडा और Flags.p1 == Flags.p1' – Gabe

+0

@Gabe' उपयोग कर सकते हैं flag.HasFlag (Flags.p1) ': hivemind! –

उत्तर

7

ऐसा कुछ?

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

सी # में 4.0 आप 'dict.Where (केवी => flag.HasFlag (kv.Key)) का उपयोग कर सकते' –

+0

मुझे पसंद @Ani, शब्दकोश और LINQ कि। नई सी # 4.0 सुविधा का उल्लेख करने के लिए @Gabe और @Callum रोजर्स के लिए धन्यवाद। – kofucii

+0

अच्छा जवाब, लेकिन विधि * बाहर * कार्रवाई-लुकअप * परिभाषित करें। –

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

यहां महत्वपूर्ण अंतर यह है कि यह नहीं बल्कि शब्दकोश में प्रविष्टियों की तुलना गणन में परिभाषित मूल्यों पर iterates है। इस तरह यदि आप शब्दकोश में जोड़ने के बिना enum में नया झंडा जोड़ते हैं, तो आप नए ध्वज का उपयोग करने का प्रयास करते समय अपवाद प्राप्त करेंगे। और यह हमेशा झंडे के क्रम में पुनरावृत्त करता है।

संबंधित मुद्दे