C # में स्विच स्टेटमेंट को बदल दें?


365

स्विच स्टेटमेंट फालोअर, प्यार switchबनाम if/else ifनिर्माण के मेरे व्यक्तिगत प्रमुख कारणों में से एक है । एक उदाहरण यहाँ क्रम में है:

static string NumberToWords(int number)
{
    string[] numbers = new string[] 
        { "", "one", "two", "three", "four", "five", 
          "six", "seven", "eight", "nine" };
    string[] tens = new string[] 
        { "", "", "twenty", "thirty", "forty", "fifty", 
          "sixty", "seventy", "eighty", "ninety" };
    string[] teens = new string[]
        { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
          "sixteen", "seventeen", "eighteen", "nineteen" };

    string ans = "";
    switch (number.ToString().Length)
    {
        case 3:
            ans += string.Format("{0} hundred and ", numbers[number / 100]);
        case 2:
            int t = (number / 10) % 10;
            if (t == 1)
            {
                ans += teens[number % 10];
                break;
            }
            else if (t > 1)
                ans += string.Format("{0}-", tens[t]);
        case 1:
            int o = number % 10;
            ans += numbers[o];

            break;
        default:
            throw new ArgumentException("number");
    }
    return ans;
}

स्मार्ट लोग cringing हैं क्योंकि string[]s को फ़ंक्शन के बाहर घोषित किया जाना चाहिए: ठीक है, वे हैं, यह केवल एक उदाहरण है।

कंपाइलर निम्नलिखित त्रुटि के साथ विफल रहता है:

नियंत्रण एक केस लेबल ('केस 3:') से दूसरे में नहीं गिर सकता है
नियंत्रण एक केस लेबल ('केस 2:') से दूसरे में नहीं गिर सकता है

क्यों? और क्या इस तरह के व्यवहार को तीन ifएस के बिना प्राप्त करने का कोई तरीका है ?

जवाबों:


648

( मेरे द्वारा अन्यत्र दिए गए उत्तर की कॉपी / पेस्ट )

के माध्यम से गिरने switch- caseमें कोई कोड case(देखें case 0), या विशेष goto case(देखें case 1) या goto default(देखें case 2) रूपों का उपयोग करके प्राप्त किया जा सकता है :

switch (/*...*/) {
    case 0: // shares the exact same code as case 1
    case 1:
        // do something
        goto case 2;
    case 2:
        // do something else
        goto default;
    default:
        // do something entirely different
        break;
}

121
मुझे लगता है कि, इस विशेष उदाहरण में, गोटो को हानिकारक नहीं माना जाता है।
थॉमस ओवंस

78
लानत - मैं 1.0 के शुरुआती दिनों से सी # के साथ प्रोग्रामिंग कर रहा हूं, और मैंने अब तक ऐसा कभी नहीं देखा। बस दिखाने के लिए जाता है, आप हर दिन नई चीजें सीखते हैं।
एरिक फोर्ब्स

37
यह सब अच्छा है, एरिक। इसका एकमात्र कारण / I / इसके बारे में पता था कि मैं संकलक सिद्धांत nerd हूं जो एक आवर्धक कांच के साथ ECMA-334 चश्मा पढ़ता है।
एलेक्स लिमैन

13
@ डनक्रम्ब: जिस समय यह सुविधा लिखी गई थी, उस समय C # ने अभी तक कोई "सॉफ्ट" कीवर्ड (जैसे 'यील्ड', 'var', 'from' और 'select') नहीं जोड़े थे, इसलिए उनके पास तीन वास्तविक विकल्प थे: 1 ) एक कठिन कीवर्ड को 'फालतू' बना दें (आप इसे एक चर नाम के रूप में उपयोग नहीं कर सकते हैं), 2) इस तरह के सॉफ्ट कीवर्ड का समर्थन करने के लिए आवश्यक कोड लिखें, 3) पहले से आरक्षित कीवर्ड का उपयोग करें। # उन पोर्टिंग कोड के लिए एक बड़ा मुद्दा था; # 2 एक काफी बड़ा इंजीनियरिंग कार्य था, जिसे मैं समझता हूं; और जिस विकल्प के साथ वे गए थे, # 3 का एक साइड बेनिफिट था: इस तथ्य के बाद कोड पढ़ने वाले अन्य देवता गोटो की आधार अवधारणा से विशेषता के बारे में जान सकते थे
एलेक्स लीमन

10
यह सब स्पष्ट गिरावट के लिए नए / विशेष कीवर्ड के बारे में बात करते हैं। क्या वे केवल 'जारी' कीवर्ड का उपयोग नहीं कर सकते थे? दूसरे शब्दों में। स्विच से बाहर निकलना या अगले मामले पर जारी रहना (गिरना)।
ताल इवन-तोव

44

"क्यों" आकस्मिक गिरावट से बचने के लिए है, जिसके लिए मैं आभारी हूं। यह C और Java में बग का कोई असामान्य स्रोत नहीं है।

समाधान गोटो का उपयोग करना है, जैसे

switch (number.ToString().Length)
{
    case 3:
        ans += string.Format("{0} hundred and ", numbers[number / 100]);
        goto case 2;
    case 2:
    // Etc
}

स्विच / केस का सामान्य डिज़ाइन मेरे विचार में थोड़ा दुर्भाग्यपूर्ण है। यह C के बहुत समीप अटक गया - कुछ उपयोगी परिवर्तन हैं जो स्कूपिंग आदि के संदर्भ में किए जा सकते हैं। संभवतः एक स्मार्ट स्विच जो पैटर्न मिलान आदि कर सकता है, सहायक होगा, लेकिन यह वास्तव में स्विच से बदलकर "स्थितियों का क्रम जांचें" है। - किस बिंदु पर एक अलग नाम के लिए बुलाया जाएगा।


1
मेरे मन में स्विच और if / ifif के बीच यही अंतर है। स्विच एक एकल चर के विभिन्न राज्यों की जाँच करने के लिए है, जबकि अगर / फारस का उपयोग किसी भी संख्या में जुड़ी चीजों की जांच करने के लिए किया जा सकता है, लेकिन जरूरी नहीं कि एक एकल, या एक ही चर।
मैथ्यू शारले

2
अगर यह आकस्मिक गिरावट को रोकने के लिए था, तो मुझे लगता है कि एक संकलक चेतावनी बेहतर होती। जैसे आपके पास एक है यदि आपके स्टेटमेंट में असाइनमेंट है:if (result = true) { }
Tal Even-Tov

3
@ तालिंव-तोव: संकलक चेतावनी वास्तव में उन मामलों के लिए होनी चाहिए जहां आप लगभग हमेशा बेहतर होने के लिए कोड को ठीक कर सकते हैं। व्यक्तिगत रूप से मैं अंतर्निहित तोड़ना पसंद करूंगा, इसलिए इसे शुरू करने में कोई समस्या नहीं होगी, लेकिन यह एक अलग मामला है।
जॉन स्कीट

26

ऐतिहासिक रूप से स्विच सॉफ़र आधुनिक सॉफ्टवेयर्स में बग के प्रमुख स्रोत हैं। भाषा डिजाइनर ने मामले के अंत में कूदना अनिवार्य करने का फैसला किया, जब तक कि आप बिना प्रसंस्करण के सीधे अगले मामले में डिफ़ॉल्ट नहीं होते।

switch(value)
{
    case 1:// this is still legal
    case 2:
}

23
मुझे अच्छी तरह से समझ में नहीं आया कि "केस 1, 2:" क्यों नहीं है
BCS 23

11
@ डेविड फ़फ़र: हाँ, यह ऐसा है और ऐसी case 1, 2:भाषाओं में है जो इसकी अनुमति देती हैं। मैं कभी नहीं समझ पाऊंगा कि कोई भी आधुनिक भाषा इस बात की अनुमति क्यों नहीं देगी।
BCS

@ बीसीओ के बयान के साथ, कई अल्पविराम से अलग किए गए विकल्पों को संभालने के लिए मुश्किल हो सकता है?
पेंगुइन

@ पेंगुट: यह कहना अधिक सटीक हो सकता है कि case 1, 2:एक एकल लेबल है, लेकिन कई नामों के साथ। - FWIW, मुझे लगता है कि अधिकांश भाषाएं जिनके द्वारा मना किया जाता है, विशेष मामले "लगातार केस लेबल" इंडियम के माध्यम से नहीं आते हैं, बल्कि केस लेबल को अगले बयान पर टिप्पणी के रूप में मानते हैं और एक (या एक) लेबल वाले बयान से पहले अंतिम विवरण की आवश्यकता होती है अधिक) केस लेबल एक छलांग है।
बीसीएस

22

यहां उत्तरों में जोड़ने के लिए, मुझे लगता है कि यह इसके साथ संयोजन के रूप में विपरीत प्रश्न पर विचार करने के लायक है, अर्थात। C ने पहले स्थान पर गिरने की अनुमति क्यों दी?

किसी भी प्रोग्रामिंग भाषा में दो लक्ष्य होते हैं:

  1. कंप्यूटर को निर्देश प्रदान करें।
  2. प्रोग्रामर के इरादों का एक रिकॉर्ड छोड़ दें।

इसलिए किसी भी प्रोग्रामिंग भाषा का निर्माण इन दो लक्ष्यों को सर्वोत्तम तरीके से पूरा करने के बीच एक संतुलन है। एक तरफ, कंप्यूटर निर्देशों में बदलना आसान है (चाहे वे मशीन कोड हों, आईएल जैसे बायटेकोड, या निष्पादन पर निर्देशों की व्याख्या की जाती है) फिर अधिक सक्षम संकलन या व्याख्या की प्रक्रिया कुशल, विश्वसनीय और होगी आउटपुट में कॉम्पैक्ट। अपनी चरम सीमा तक, यह लक्ष्य हमारे विधानसभा, आईएल या यहां तक ​​कि कच्चे ऑप-कोड में लिखने का परिणाम है, क्योंकि सबसे आसान संकलन वह है जहां कोई संकलन नहीं है।

इसके विपरीत, भाषा जितनी अधिक प्रोग्रामर के इरादे को व्यक्त करती है, उस अंत तक ले जाने वाले साधनों की बजाय, लिखने और रखरखाव के दौरान कार्यक्रम को समझने में उतना ही अधिक समझ में आता है।

अब, switchहमेशा इसे if-elseब्लॉकों या समान के बराबर श्रृंखला में परिवर्तित करके संकलित किया जा सकता था, लेकिन इसे एक विशेष आम विधानसभा पैटर्न में संकलन की अनुमति के रूप में डिज़ाइन किया गया था, जहां कोई मान लेता है, उससे एक ऑफसेट गणना करता है (चाहे एक तालिका देख कर। मूल्य के एक आदर्श हैश द्वारा अनुक्रमित, या मूल्य पर वास्तविक अंकगणित द्वारा *)। यह इस बिंदु पर ध्यान देने योग्य है कि आज, सी # संकलन कभी-कभी switchसमकक्ष में बदल जाएगा if-else, और कभी-कभी हैश-आधारित कूद दृष्टिकोण का उपयोग करें (और इसी तरह सी, सी ++, और तुलनीय वाक्यविन्यास के साथ अन्य भाषाओं में)।

इस मामले में गिरावट की अनुमति देने के दो अच्छे कारण हैं:

  1. यह वैसे भी स्वाभाविक रूप से होता है: यदि आप निर्देशों के एक सेट में एक जंप टेबल का निर्माण करते हैं, और निर्देशों के पहले बैचों में किसी प्रकार का कूद या रिटर्न नहीं होता है, तो निष्पादन अगले बैच में स्वाभाविक रूप से प्रगति करेगा। यदि आप switch-यूज़िंग सी को जंप-टेबल-मशीन मशीन के उपयोग से चालू करते हैं, तो गिरने के माध्यम से अनुमति देना "क्या होगा" ।

  2. असेंबली में लिखने वाले कोडर्स पहले से ही समतुल्य थे: जब असेंबली में हाथ से एक जंप टेबल लिखते हैं, तो उन्हें इस पर विचार करना होगा कि क्या कोड का दिया गया ब्लॉक रिटर्न के साथ समाप्त होगा, टेबल के बाहर कूद, या बस जारी रहेगा अगले ब्लॉक के लिए। जैसे, breakजब आवश्यक हो तो कोडर को स्पष्ट रूप से जोड़ना "कोडर के लिए" स्वाभाविक था।

इसलिए उस समय, यह एक कंप्यूटर भाषा के दो लक्ष्यों को संतुलित करने का एक उचित प्रयास था क्योंकि यह उत्पादित मशीन कोड और स्रोत कोड की अभिव्यंजना दोनों से संबंधित है।

चार दशक बाद हालांकि, कुछ कारणों से चीजें समान नहीं हैं:

  1. C में कोडर्स का आज कम या कोई असेंबली अनुभव नहीं हो सकता है। कई अन्य सी-शैली भाषाओं में कोडर भी (विशेष रूप से जावास्क्रिप्ट!) की संभावना कम है। "असेंबली से लोगों का क्या उपयोग किया जाता है" की कोई भी अवधारणा अब प्रासंगिक नहीं है।
  2. ऑप्टिमाइज़ेशन में सुधार का अर्थ है कि switchया तो होने की संभावनाif-else क्योंकि इसे दृष्टिकोण को सबसे अधिक कुशल माना जाता था, या फिर जंप-टेबल दृष्टिकोण के विशेष रूप से गूढ़ रूप में बदल दिया जाता है। उच्च और निचले स्तर के दृष्टिकोणों के बीच मानचित्रण उतना मजबूत नहीं है जितना एक बार था।
  3. अनुभव से पता चला है कि फॉल-थ्रू के बजाय मानक के बजाय अल्पसंख्यक का मामला है (सूर्य के संकलक के एक अध्ययन में पाया गया कि 3% switchब्लॉकों ने एक ही ब्लॉक पर कई लेबल के अलावा अन्य फ़ॉल-थ्रू का उपयोग किया था, और यह सोचा गया था कि उपयोग- यहां केस का मतलब है कि यह 3% वास्तव में सामान्य से बहुत अधिक था)। इसलिए अध्ययन की गई भाषा आम की तुलना में असामान्य रूप से अधिक आसानी से कैटरिंग-इन बनाती है।
  4. अनुभव ने दिखाया है कि फॉल-थ्रू उन मामलों में दोनों समस्याओं का स्रोत बन जाता है जहां यह गलती से किया जाता है, और उन मामलों में भी जहां सही फॉल-थ्रू किसी को कोड बनाए रखने से चूक जाता है। यह उत्तरार्द्ध फॉल-थ्रू से जुड़े बग के लिए एक सूक्ष्म अतिरिक्त है, क्योंकि भले ही आपका कोड पूरी तरह से बग-मुक्त हो, फिर भी आपका फ़ॉल-थ्रू समस्या पैदा कर सकता है।

उन अंतिम दो बिंदुओं से संबंधित, K & R के वर्तमान संस्करण के निम्नलिखित उद्धरण पर विचार करें:

एक मामले से दूसरे में गिरना मजबूत नहीं है, जब कार्यक्रम को संशोधित किया जाता है तो विघटन होने का खतरा होता है। एक एकल संगणना के लिए कई लेबल के अपवाद के साथ, फॉल-थ्रू को संयम से इस्तेमाल किया जाना चाहिए, और टिप्पणी की जानी चाहिए।

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

तो, घोड़े के मुंह से, सी में गिरना समस्याग्रस्त है। इसे हमेशा टिप्पणियों के साथ गिरने वाले दस्तावेज़ों के लिए अच्छा अभ्यास माना जाता है, जो सामान्य सिद्धांत का एक अनुप्रयोग है कि व्यक्ति को दस्तावेज़ करना चाहिए जहां कोई असामान्य चीज़ करता है, क्योंकि यही वह है जो कोड की बाद की परीक्षा की यात्रा करेगा और / या अपना कोड जैसा बना देगा यह वास्तव में सही है, जब इसमें एक नौसिखिया बग है।

और जब आप इसके बारे में सोचते हैं, तो कोड इस तरह होता है:

switch(x)
{
  case 1:
   foo();
   /* FALLTHRU */
  case 2:
    bar();
    break;
}

है कुछ जोड़ने गिरावट के माध्यम से कोड में स्पष्ट बनाने के लिए, यह सिर्फ कुछ है कि पता लगाया जा सकता है (या जिसका अभाव पाया जा सकता है) संकलक द्वारा नहीं है।

इस प्रकार, इस तथ्य पर कि C # में फॉल-थ्रू के साथ स्पष्ट होना पड़ता है, वैसे लोगों के लिए कोई जुर्माना नहीं जोड़ता है जो अन्य सी-शैली की भाषाओं में अच्छी तरह से लिखते हैं, क्योंकि वे पहले से ही अपने पतन के माध्यम से स्पष्ट होंगे।

अंत में, gotoयहाँ का उपयोग पहले से ही C और ऐसी अन्य भाषाओं से एक आदर्श है:

switch(x)
{
  case 0:
  case 1:
  case 2:
    foo();
    goto below_six;
  case 3:
    bar();
    goto below_six;
  case 4:
    baz();
    /* FALLTHRU */
  case 5:
  below_six:
    qux();
    break;
  default:
    quux();
}

इस तरह के मामले में जहां हम चाहते हैं कि एक ब्लॉक को कोड में शामिल किया जाना चाहिए, जो केवल एक मूल्य के अलावा किसी अन्य को शामिल करता है, जो पूर्ववर्ती ब्लॉक में लाता है, तो हम पहले से ही उपयोग कर रहे हैं goto। (बेशक, अलग-अलग सशर्त के साथ इससे बचने के साधन और तरीके हैं लेकिन यह इस सवाल से संबंधित हर चीज के बारे में सच है)। जैसे कि C # एक स्थिति से निपटने के लिए पहले से ही सामान्य तरीके से बनाया गया है, जहाँ हम कोड के एक से अधिक ब्लॉक को हिट करना चाहते हैं switch, और साथ ही इसे फॉल-थ्रू कवर करने के लिए सामान्यीकृत किया है। इसने दोनों मामलों को और अधिक सुविधाजनक और स्व-दस्तावेजीकरण बना दिया, क्योंकि हमें C में एक नया लेबल जोड़ना है, लेकिन caseC # में लेबल के रूप में उपयोग कर सकते हैं । C # में हम below_sixलेबल से छुटकारा पा सकते हैं और उपयोग कर सकते हैं goto case 5जो कि स्पष्ट है कि हम क्या कर रहे हैं। (हमें भी जोड़ना होगाbreakउसके लिए default, जिसे मैंने उपरोक्त C कोड स्पष्ट रूप से C # कोड नहीं बनाने के लिए छोड़ा था)।

इसलिए संक्षेप में:

  1. C # अब 40 वर्ष पहले (न ही C इन दिनों में) C कोड के रूप में सीधे अनियंत्रित संकलक आउटपुट से संबंधित है, जो कि अप्रासंगिक के पतन के प्रेरणाओं में से एक बनाता है।
  2. C # breakसमान भाषाओं से परिचित लोगों द्वारा भाषा को आसानी से सीखने, और आसान पोर्टिंग करने के लिए C का अर्थ निहित नहीं है ।
  3. सी # पिछले चार दशकों से समस्याओं के कारण के रूप में अच्छी तरह से प्रलेखित कीड़े या गलत कोड के संभावित स्रोत को हटाता है।
  4. C # कंपाइलर द्वारा लागू करने योग्य C (डॉक्युमेंट फॉल) के साथ मौजूदा बेस्ट-प्रैक्टिस करता है।
  5. C # असामान्य मामले को अधिक स्पष्ट कोड के साथ बनाता है, सामान्य केस कोड के साथ एक स्वचालित रूप से लिखता है।
  6. C # gotoसमान caseलेबल से एक ही ब्लॉक को हिट करने के लिए एक ही- आधारित दृष्टिकोण का उपयोग करता है जैसा कि C में उपयोग किया जाता है। यह इसे कुछ अन्य मामलों में सामान्य करता है।
  7. C # लेबल के रूप में कार्य करने की gotoअनुमति देकर C की तुलना में उस- आधारित दृष्टिकोण को अधिक सुविधाजनक और स्पष्ट बनाता है case

सब सब में, एक बहुत ही उचित डिजाइन निर्णय


* BASIC के कुछ रूपों में से एक को GOTO (x AND 7) * 50 + 240भंगुर करते समय पसंद करने की अनुमति दी जा सकती है और इसलिए प्रतिबंध लगाने के लिए एक विशेष रूप से प्रेरक मामला है goto, जो उच्च-स्तरीय कोड के बराबर उच्च-भाषा दिखाने के लिए काम करता है जो निम्न-स्तरीय कोड के आधार पर एक छलांग लगा सकता है। एक मूल्य पर अंकगणित, जो कि अधिक उचित है जब यह संकलन के परिणाम के बजाय कुछ है जो मैन्युअल रूप से बनाए रखा जाना है। विशेष रूप से डफ़ डिवाइस के कार्यान्वयन खुद को बराबर मशीन कोड या आईएल के लिए अच्छी तरह से उधार देते हैं क्योंकि निर्देशों के प्रत्येक ब्लॉक को अक्सर nopभराव के अतिरिक्त की आवश्यकता के बिना एक ही लंबाई होगी ।

A डफ का उपकरण एक उचित अपवाद के रूप में फिर से यहां आता है। तथ्य यह है कि उस और इसी तरह के पैटर्न के साथ ऑपरेशन का दोहराव उस प्रभाव के लिए एक स्पष्ट टिप्पणी के बिना भी गिरने के माध्यम से अपेक्षाकृत स्पष्ट उपयोग करने का कार्य करता है।


17

आप 'गोटो केस लेबल' http://www.blackwasp.co.uk/CSharpGoto.aspx कर सकते हैं

गोटो स्टेटमेंट एक साधारण कमांड है जो बिना किसी प्रोग्राम के कंट्रोल को दूसरे स्टेटमेंट में ट्रांसफर करता है। कमांड की अक्सर कुछ डेवलपर्स के साथ आलोचना की जाती है जो सभी उच्च-स्तरीय प्रोग्रामिंग भाषाओं से इसे हटाने की वकालत करते हैं क्योंकि इससे स्पेगेटी कोड हो सकता है । यह तब होता है जब बहुत सारे गोटो स्टेटमेंट्स या समान जम्प स्टेटमेंट्स होते हैं जो कोड को पढ़ना और बनाए रखना मुश्किल हो जाता है। हालांकि, ऐसे प्रोग्रामर हैं जो बताते हैं कि गोटो स्टेटमेंट, जब सावधानी से उपयोग किया जाता है, तो कुछ समस्याओं का एक सुरुचिपूर्ण समाधान प्रदान करता है ...


8

उन्होंने इस व्यवहार को डिजाइन द्वारा छोड़ दिया जब बचने के लिए इसका उपयोग नहीं किया गया लेकिन समस्याओं का कारण बना।

इसका उपयोग केवल तभी किया जा सकता है जब केस भाग में कोई बयान न हो, जैसे:

switch (whatever)
{
    case 1:
    case 2:
    case 3: boo; break;
}

4

उन्होंने c # के लिए स्विच स्टेटमेंट (C / Java / C ++ से) व्यवहार को बदल दिया। मुझे लगता है कि तर्क यह था कि लोग गिरावट के बारे में भूल गए और त्रुटियों का कारण बना। मैंने जो एक किताब पढ़ी, उसमें कहा गया कि अनुकरण करने के लिए गोटो का उपयोग करें, लेकिन यह मेरे लिए एक अच्छे समाधान की तरह नहीं है।


2
C # गोटो का समर्थन करता है, लेकिन परित्याग नहीं? वाह। और यह सिर्फ उन नहीं है। C # एकमात्र ऐसी भाषा है जो मुझे पता है कि इस तरह से व्यवहार करता है।
मैथ्यू शार्ले

मुझे यह बिल्कुल पसंद नहीं था, लेकिन "फॉल-थ्रू" वास्तव में आपदा के लिए एक नुस्खा है (विशेष रूप से जूनियर प्रोग्रामर के बीच।) जैसा कि कई ने बताया है, सी # अभी भी खाली लाइनों के लिए फॉल-थ्रू की अनुमति देता है (जो कि बहुमत है मामलों।) "केनी" ने एक लिंक पोस्ट किया जो स्विच-केस के साथ सुरुचिपूर्ण गोटो के उपयोग पर प्रकाश डालता है।
प्रेट्ज़ेल

यह मेरी राय में बहुत बड़ी बात नहीं है। उस समय का 99% मैं नहीं चाहता हूं कि मैं अतीत में बग से जल चुका हूं।
केन

1
"यह मेरे लिए एक अच्छे समाधान की तरह नहीं है" - आपके बारे में यह सुनकर खेद है, क्योंकि यही goto caseहै। गिरावट पर इसका लाभ यह है कि यह स्पष्ट है। यहाँ कुछ लोगों को इस बात पर आपत्ति है goto caseकि वे मुद्दे की किसी भी समझ के बिना "गोटो" के खिलाफ प्रेरित थे और अपने दम पर सोचने में असमर्थ हैं। जब दिज्क्स्ट्रा ने "गोटो का विचार हानिकारक" लिखा, वह उन भाषाओं को संबोधित कर रहे थे जिनके पास नियंत्रण प्रवाह को बदलने का कोई अन्य साधन नहीं था।
जिम बेल्टर

@JimBalter और फिर कितने लोग जो उस पर दिक्क्स्ट्रा को उद्धृत करते हैं, नथ को उद्धृत करेंगे कि "समय से पहले अनुकूलन सभी बुराई की जड़ है" हालांकि वह उद्धरण था जब नूथ स्पष्ट रूप से लिख रहा था कि gotoकोड का अनुकूलन करते समय यह कितना उपयोगी हो सकता है?
जॉन हैना

1

आप गोटो कीवर्ड द्वारा c ++ की तरह गिर सकते हैं।

पूर्व:

switch(num)
{
   case 1:
      goto case 3;
   case 2:
      goto case 3;
   case 3:
      //do something
      break;
   case 4:
      //do something else
      break;
   case default:
      break;
}

9
यदि केवल किसी ने दो साल पहले पोस्ट किया था!

0

प्रत्येक केस ब्लॉक के बाद एक ब्रेक स्टेटमेंट जैसे ब्रेक की आवश्यकता होती है, जिसमें आखिरी ब्लॉक भी शामिल है चाहे वह केस स्टेटमेंट हो या डिफॉल्ट स्टेटमेंट। एक अपवाद के साथ, (C ++ स्विच स्टेटमेंट के विपरीत), C # एक केस लेबल से दूसरे में निहित गिरावट का समर्थन नहीं करता है। एक अपवाद है यदि किसी केस स्टेटमेंट में कोई कोड नहीं है।

- सी # स्विच () प्रलेखन


1
मुझे लगता है कि इस व्यवहार को प्रलेखित किया गया है, मैं जानना चाहता हूं कि यह ऐसा क्यों है और पुराने व्यवहार को प्राप्त करने के लिए कोई भी विकल्प है।
मैथ्यू शार्ले

0

प्रत्येक केस स्टेटमेंट के बाद एक डिफ़ॉल्ट केस होने पर भी ब्रेक या गोटो स्टेटमेंट की आवश्यकता होती है।


2
यदि केवल किसी ने दो साल पहले पोस्ट किया था!

1
@ पोल्डी यह पहली बार मजेदार था ... शिल्पा को आपको हर मामले के लिए ब्रेक या गोटो की आवश्यकता नहीं है, बस हर मामले के लिए यह अपना कोड है। आपके पास कई मामले हो सकते हैं जो कोड को ठीक साझा करते हैं।
मैवरिक

0

बस एक त्वरित नोट जोड़ने के लिए कि Xamarin के लिए संकलक वास्तव में यह गलत है और यह गिरावट की अनुमति देता है। यह निश्चित रूप से तय किया गया है, लेकिन जारी नहीं किया गया है। कुछ कोड में यह पता चला है कि वास्तव में के माध्यम से गिर रहा था और संकलक ने शिकायत नहीं की।


0

स्विच (C # संदर्भ) कहते हैं

अंतिम # सहित स्विच अनुभागों के अंत में C # की आवश्यकता होती है,

इसलिए आपको break;अपने defaultअनुभाग में एक जोड़ने की आवश्यकता है , अन्यथा अभी भी एक कंपाइलर त्रुटि होगी।


Thx, इसने मेरी मदद की;)
CareTaker22

-1

C # स्विच / केस स्टेटमेंट के माध्यम से गिरने का समर्थन नहीं करता है। यकीन नहीं क्यों, लेकिन इसके लिए वास्तव में कोई समर्थन नहीं है। कड़ी


यह तो गलत है। अन्य उत्तर देखें ... एक स्पष्ट गिरावट के प्रभाव को स्पष्ट रूप से प्राप्त किया जा सकता है goto case। यह सी # डिजाइनरों द्वारा एक जानबूझकर, बुद्धिमान डिजाइन विकल्प था।
जिम बाल्टर

-11

आप "ब्रेक" जोड़ना भूल गए; कथन 3 में। यदि आपने इसे ब्लॉक में लिखा है तो 2 मामले में। इसलिए यह प्रयास करें:

case 3:            
{
    ans += string.Format("{0} hundred and ", numbers[number / 100]);
    break;
}


case 2:            
{
    int t = (number / 10) % 10;            
    if (t == 1)            
    {                
        ans += teens[number % 10];                
    }            
    else if (t > 1)                
    {
        ans += string.Format("{0}-", tens[t]);        
    }
    break;
}

case 1:            
{
    int o = number % 10;            
    ans += numbers[o];            
    break;        
}

default:            
{
    throw new ArgumentException("number");
}

2
यह काफी गलत आउटपुट उत्पन्न करता है। मैंने डिज़ाइन द्वारा स्विच स्टेटमेंट को छोड़ दिया। सवाल यह है कि C # संकलक इसे एक त्रुटि के रूप में देखता है जब लगभग किसी अन्य भाषा में यह प्रतिबंध नहीं है।
मैथ्यू शार्ले

5
क्या एक आश्चर्यजनक विफलता को समझने के लिए। और आपके पास इसे हटाने के लिए 5 साल हैं और अभी भी ऐसा नहीं किया है? डरावना।
जिम बाल्टर 24:13
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.