c# - स्विच स्टेटमेंट में कई मामले




switch-statement (10)

.NET Framework 3.5 में श्रेणियां हैं:

एमएसडीएन से गणना योग्य। रेंज

आप इसे "शामिल" और आईएफ कथन के साथ उपयोग कर सकते हैं, क्योंकि किसी ने कहा है कि स्विच स्टेटमेंट "==" ऑपरेटर का उपयोग करता है।

यहां एक उदाहरण दिया गया है:

int c = 2;
if(Enumerable.Range(0,10).Contains(c))
    DoThing();
else if(Enumerable.Range(11,20).Contains(c))
    DoAnotherThing();

लेकिन मुझे लगता है कि हम और अधिक मजेदार हो सकते हैं: क्योंकि आपको रिटर्न वैल्यू की आवश्यकता नहीं होगी और यह क्रिया पैरामीटर नहीं लेती है, आप आसानी से क्रियाओं का उपयोग कर सकते हैं!

public static void MySwitchWithEnumerable(int switchcase, int startNumber, int endNumber, Action action)
{
    if(Enumerable.Range(startNumber, endNumber).Contains(switchcase))
        action();
}

इस नई विधि के साथ पुराना उदाहरण:

MySwitchWithEnumerable(c, 0, 10, DoThing);
MySwitchWithEnumerable(c, 10, 20, DoAnotherThing);

चूंकि आप कार्यवाही कर रहे हैं, मूल्यों के नहीं, आपको कोष्ठक छोड़ना चाहिए, यह बहुत महत्वपूर्ण है। यदि आपको तर्कों के साथ फ़ंक्शन की आवश्यकता है, तो Action के प्रकार Action<ParameterType> को बदलें। यदि आपको वापसी मूल्यों की आवश्यकता है, तो Func<ParameterType, ReturnType>

सी # 3.0 में केस पैरामीटर समान तथ्य को समाहित करने के लिए कोई आसान आंशिक अनुप्रयोग नहीं है, लेकिन आप थोड़ा सहायक विधि बनाते हैं (थोड़ा वर्बोज़, था)।

public static void MySwitchWithEnumerable(int startNumber, int endNumber, Action action){ 
    MySwitchWithEnumerable(3, startNumber, endNumber, action); 
}

यहां एक उदाहरण है कि नए कार्यात्मक आयातित कथन आईएमएचओ पुराने अनिवार्य से अधिक शक्तिशाली और सुरुचिपूर्ण हैं।

case value: बताए बिना कई केस स्टेटमेंट्स के माध्यम से गिरने का कोई तरीका है case value: बार-बार?

मुझे यह काम पता है:

switch (value)
{
   case 1:
   case 2:
   case 3:
      //do some stuff
      break;
   case 4:
   case 5:
   case 6:
      //do some different stuff
      break;
   default:
       //default stuff
      break;
}

लेकिन मैं ऐसा कुछ करना चाहता हूं:

switch (value)
{
   case 1,2,3:
      //Do Something
      break;
   case 4,5,6:
      //Do Something
      break;
   default:
      //Do the Default
      break;
}

क्या यह वाक्यविन्यास मैं एक अलग भाषा से सोच रहा हूं, या क्या मुझे कुछ याद आ रहा है?


@ जेनिफर ओवेन्स: आप बिल्कुल सही हैं नीचे दिए गए कोड काम नहीं करेंगे:

case 1 | 3 | 5:
//not working do something

ऐसा करने का एकमात्र तरीका यह है:

case 1: case 2: case 3:
// do something
break;

जिस कोड को आप ढूंढ रहे हैं वह विजुअल बेसिक पर काम करता है जहां आप आसानी से रेंज डाल सकते हैं ... स्विच के किसी भी विकल्प में या यदि सुविधाजनक सुविधाजनक नहीं है, तो मैं बहुत ही चरम बिंदु पर सुझाव देता हूं, दृश्य मूलभूत और आयात के साथ .dll बना देता हूं। आपके सी # परियोजना के लिए।

नोट: विजुअल बेसिक में समकक्ष स्विच का चयन केस है।


आप नई लाइन छोड़ सकते हैं जो आपको देता है:

case 1: case 2: case 3:
   break;

लेकिन मैं उस बुरी शैली पर विचार करता हूं।


आपके द्वारा उल्लिखित दूसरी विधि के लिए सी ++ और न ही सी # में कोई वाक्यविन्यास नहीं है।

आपकी पहली विधि में कुछ भी गलत नहीं है। यदि आपके पास बहुत बड़ी श्रेणियां हैं, तो बस कथन की एक श्रृंखला का उपयोग करें।


एक और विकल्प एक नियमित का उपयोग करना होगा। यदि मामले 1-3 सभी एक ही तर्क को निष्पादित करते हैं तो उस तर्क को नियमित रूप से लपेटें और प्रत्येक मामले के लिए इसे कॉल करें। मुझे पता है कि यह वास्तव में केस स्टेटमेंट से छुटकारा नहीं पाता है, लेकिन यह अच्छी शैली को लागू करता है और न्यूनतम रखरखाव रखता है .....

[संपादित करें] मूल प्रश्न से मेल खाने के लिए वैकल्पिक कार्यान्वयन जोड़ा गया ... [/ संपादित करें]

switch (x)
{
   case 1:
      DoSomething();
      break;
   case 2:
      DoSomething();
      break;
   case 3:
      DoSomething();
      break;
   ...
}

private void DoSomething()
{
   ...
}

ऑल्ट

switch (x)
{
   case 1:
   case 2:
   case 3:
      DoSomething();
      break;
   ...
}

private void DoSomething()
{
   ...
}

दरअसल मुझे गोटो कमांड भी पसंद नहीं है, लेकिन यह आधिकारिक एमएस सामग्री में है, यहां सभी अनुमत वाक्यविन्यास हैं।

यदि स्विच अनुभाग की कथन सूची का अंतिम बिंदु पहुंच योग्य है, तो संकलन-समय त्रुटि उत्पन्न होती है। इसे "नो फॉल थ्रू" नियम के रूप में जाना जाता है। उदाहरण

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
default:
   CaseOthers();
   break;
}

मान्य है क्योंकि कोई स्विच सेक्शन में पहुंचने योग्य अंत बिंदु नहीं है। सी और सी ++ के विपरीत, स्विच अनुभाग के निष्पादन को अगले स्विच अनुभाग में "गिरने" की अनुमति नहीं है, और उदाहरण

switch (i) {
case 0:
   CaseZero();
case 1:
   CaseZeroOrOne();
default:
   CaseAny();
}

संकलन-समय त्रुटि में परिणाम। स्विच स्विच का निष्पादन किसी अन्य स्विच सेक्शन के निष्पादन के बाद किया जाना चाहिए, एक स्पष्ट गोटो केस या गोटो डिफॉल्ट कथन का उपयोग किया जाना चाहिए:

switch (i) {
case 0:
   CaseZero();
   goto case 1;
case 1:
   CaseZeroOrOne();
   goto default;
default:
   CaseAny();
   break;
}

स्विच-सेक्शन में एकाधिक लेबल की अनुमति है। उदाहरण

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
case 2:
default:
   CaseTwo();
   break;
}

मुझे इस विशेष मामले में विश्वास है, गोटो का उपयोग किया जा सकता है, यह वास्तव में गिरने का एकमात्र तरीका है।

स्रोत: http://msdn.microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx


मूल प्रश्न के लिए थोड़ा देर हो चुकी है, लेकिन मैं इस उत्तर को उम्मीद में पोस्ट कर रहा हूं कि कोई नया संस्करण ( सी # 7 - विजुअल स्टूडियो 2017 / .NET Framework 4.6.2 में डिफ़ॉल्ट रूप से उपलब्ध ) का उपयोग करके इसे उपयोगी लगेगा।

सी # 7 में, स्विच स्टेटमेंट के साथ रेंज-आधारित स्विचिंग अब संभव है और ओपी की समस्या से मदद मिलेगी।

उदाहरण:

int i = 5;

switch (i)
{
    case int n when (n >= 7):
        Console.WriteLine($"I am 7 or above: {n}");
        break;

    case int n when (n >= 4 && n <= 6 ):
        Console.WriteLine($"I am between 4 and 6: {n}");
        break;

    case int n when (n <= 3):
        Console.WriteLine($"I am 3 or less: {n}");
        break;
}

// Output: I am between 4 and 6: 5

टिप्पणियाँ:

  • when स्थिति में कोष्ठक ( और ) आवश्यकता नहीं होती है, लेकिन इस उदाहरण में तुलना (ओं) को हाइलाइट करने के लिए उपयोग की जाती है।
  • int का उपयोग int बदले भी किया जा सकता है। उदाहरण के लिए: case var n when n >= 7: :।

यदि आपके पास स्ट्रिंग (या किसी अन्य प्रकार) की एक बड़ी मात्रा है, तो सभी एक ही काम कर रहे हैं, मैं स्ट्रिंग के साथ संयुक्त स्ट्रिंग सूची के उपयोग की सिफारिश करता हूं। संपत्ति शामिल है।

तो यदि आपके पास एक बड़ा स्विच स्टेटमेंट है तो:

switch (stringValue)
{
    case "cat":
    case "dog":
    case "string3":
    ...
    case "+1000 more string": //Too many string to write a case for all!
        //Do something;
    case "a lonely case"
        //Do something else;
    .
    .
    .
}

आप इसे इस तरह के कथन के साथ प्रतिस्थापित करना चाहेंगे:

//Define all the similar "case" string in a List
List<string> listString = new List<string>(){ "cat", "dog", "string3", "+1000 more string"};
//Use string.Contains to find what you are looking for
if (listString.Contains(stringValue))
{
    //Do something;
}
else
{
    //Then go back to a switch statement inside the else for the remaining cases if you really need to
}

स्ट्रिंग केस की किसी भी संख्या के लिए यह स्केल अच्छी तरह से है।


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

आइए उदाहरण के लिए आप एक ज्ञात रेंज में मूल्यों का त्वरित परीक्षण करना चाहते हैं ताकि यह देखने के लिए कि वे प्रमुख संख्या हैं या नहीं। आप अपने कोड को अपर्याप्त गणना करने से बचना चाहते हैं और आप जिस श्रेणी में ऑनलाइन चाहते हैं उसमें प्राइम की एक सूची पा सकते हैं। ज्ञात प्राइम नंबरों पर प्रत्येक मान की तुलना करने के लिए आप एक बड़े स्विच स्टेटमेंट का उपयोग कर सकते हैं।

या आप केवल प्राइम्स का सरणी नक्शा बना सकते हैं और तत्काल परिणाम प्राप्त कर सकते हैं:

    bool[] Primes = new bool[] {
        false, false, true, true, false, true, false,    
        true, false, false, false, true, false, true,
        false,false,false,true,false,true,false};
    private void button1_Click(object sender, EventArgs e) {
        int Value = Convert.ToInt32(textBox1.Text);
        if ((Value >= 0) && (Value < Primes.Length)) {
            bool IsPrime = Primes[Value];
            textBox2.Text = IsPrime.ToString();
        }
    }

शायद आप देखना चाहते हैं कि स्ट्रिंग में एक वर्ण हेक्साडेसिमल है या नहीं। आप एक असभ्य और कुछ बड़े स्विच स्टेटमेंट का उपयोग कर सकते हैं।

या आप char का परीक्षण करने के लिए नियमित अभिव्यक्तियों का उपयोग कर सकते हैं या ज्ञात हेक्साडेसिमल अक्षरों की एक स्ट्रिंग में char की खोज के लिए इंडेक्सऑफ फ़ंक्शन का उपयोग कर सकते हैं:

        private void textBox2_TextChanged(object sender, EventArgs e) {
        try {
            textBox1.Text = ("0123456789ABCDEFGabcdefg".IndexOf(textBox2.Text[0]) >= 0).ToString();
        } catch {
        }
    }

आइए हम कहें कि आप एक मूल्य के आधार पर 3 अलग-अलग कार्रवाइयों में से एक करना चाहते हैं जो 1 से 24 की सीमा होगी। मैं आईएफ स्टेटमेंट के सेट का उपयोग करने का सुझाव दूंगा। और यदि वह बहुत जटिल हो गया (या 1 से 9 0 की सीमा में मूल्य के आधार पर संख्याएं 5 अलग-अलग कार्रवाइयां बड़ी थीं) तो क्रियाओं को परिभाषित करने और enums के सरणी मानचित्र बनाने के लिए एक enum का उपयोग करें। मूल्य का उपयोग सरणी मानचित्र में अनुक्रमित करने के लिए किया जाएगा और आप जिस क्रिया को चाहते हैं उसे प्राप्त करें। फिर परिणामी एनम मूल्य को संसाधित करने के लिए या तो आईएफ स्टेटमेंट का एक छोटा सा सेट या एक बहुत ही सरल स्विच स्टेटमेंट का उपयोग करें।

साथ ही, एक सरणी मानचित्र के बारे में अच्छी बात जो मूल्यों की एक श्रृंखला को क्रियाओं में परिवर्तित करती है वह यह है कि इसे आसानी से कोड द्वारा बदला जा सकता है। हार्ड वायर्ड कोड के साथ आप आसानी से रनटाइम पर व्यवहार नहीं बदल सकते हैं लेकिन एक सरणी मानचित्र के साथ यह आसान है।


सी # में स्विच का एक कम ज्ञात पहलू यह है कि यह ऑपरेटर पर निर्भर करता है = और चूंकि इसे ओवरराइड किया जा सकता है, तो आपके पास ऐसा कुछ हो सकता है:


string s = foo();

switch (s) {
  case "abc": /*...*/ break;
  case "def": /*...*/ break;
}






switch-statement