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


581

क्या 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;
}

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


क्या कोई कारण है कि आप सिर्फ एक IF स्टेटमेंट का उपयोग नहीं करते हैं (यदि आप किसी श्रेणी की जाँच कर रहे हैं)?
एरिक शूनओवर

2
हाँ, चार्लीज़, पहला तरीका ठीक काम करता है, मैंने इसे कई जगहों पर इस्तेमाल किया है। यह जितना मुझे पसंद है, उससे अधिक गंदा है, लेकिन यह उपयोगी है। मैंने केवल उन पूर्णांकों को एक उदाहरण के रूप में प्रयोग किया है। वास्तविक डेटा अधिक विविध था। अगर (1 || 2 || 3) {...} तो और (4 || 5 || 6) {...} भी काम किया होता, लेकिन इसे पढ़ना कठिन है।
थियो

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

1
आपने रूबी से दूसरा सिंटैक्स चुना होगा। इस तरह से यह उस भाषा में काम करता है (हालांकि स्विच मामला बन जाता है, और मामला तब बन जाता है, जब अन्य चीजों के बीच।)
जुआनपाको

4
महत्वपूर्ण नोट । C # v7 से शुरू होने वाले स्विच केस में रेंज का समर्थन किया जाता है - कृपया स्टीव जी का उत्तर देखें
RBT

जवाबों:


313

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

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


5
एक अतिरिक्त के रूप में मैं पर MSDN पर उपलब्ध सी # भाषा विनिर्देश के लिए एक लिंक जोड़ना चाहते थे msdn.microsoft.com/en-us/vcsharp/aa336809.aspx
रिचर्ड McGuire

एनम के सेट पर इनपुट को कम करने और एनम पर स्विच करने के लिए उपयोगकर्ता कुछ (या टेबल लुकअप) का उपयोग कर सकता है।
हार्वे

5
शायद VB.net से
जॉर्ज बीरबिलिस

1
VB.net विभिन्न केस स्टेटमेंट्स के लिए बेहतर है ... सिवाय इसके कि वे C # do की तरह नहीं गिरते। थोड़ा ले लो, थोड़ा दे दो।
ब्रेन 2000

मेरा मानना ​​है कि यह अब सही नहीं है। देखें stackoverflow.com/questions/20147879/… । इसके अलावा इस सवाल पर एक जवाब है stackoverflow.com/a/44848705/1073157
डैन रेसन

699

मुझे लगता है कि यह पहले ही उत्तर दिया जा चुका है। हालाँकि, मुझे लगता है कि आप अभी भी दोनों विकल्पों को मिलाकर एक बेहतर तरीके से कर सकते हैं:

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

3
'स्विच' को c # के लिए कमतर होना चाहिए?
ऑस्टिन हैरिस

3
ध्वस्त कोड प्रश्न में पहले उदाहरण के लिए लंबा हो जाता है। हो सकता है कि यह ठीक उसी तरह से हो जैसे सवाल में है।
19

10
क्यों परेशान? विजुअल स्टूडियो 2013 में ऑटो इंडेंटर मूल प्रश्न में प्रारूप में इसे वापस कर देगा।
गुस्ताव

14
@T_D को समर्थन मिल रहा है क्योंकि यह वास्तव में सवाल का जवाब देता है। ओपी ने कहा, क्या मैं कुछ याद कर रहा हूं ... कार्लोस ने जवाब दिया कि वह क्या याद कर रहा था। मुझे बहुत काट दिया और सूख गया। नफरत नहीं है कि वह 422 upvotes मिला है।
माइक डेवेनी

8
@MikeDevenney फिर आपने प्रश्न की अलग से व्याख्या की, जहाँ तक मुझे लगता है कि सही उत्तर "नहीं, c # है, उसके लिए कोई वाक्यविन्यास नहीं है"। अगर कोई पूछता है "क्या मैं एक गिलास में तरल डालना संभव है जो मैं उल्टा पकड़ रहा हूं?" उत्तर "नहीं" होना चाहिए न कि "आप तरल डाल सकते हैं यदि आप इसे उल्टा देखते हैं और अपनी कल्पना का उपयोग करते हैं", क्योंकि यह उत्तर कल्पना का उपयोग करने के बारे में है। यदि आप नियमित वाक्यविन्यास का उपयोग करते हैं, लेकिन कुछ कल्पना के साथ यह अन्य वाक्यविन्यास की तरह बुरी तरह से प्रारूपित होता है। उम्मीद है कि आप मेरी बात ...: P
T_D

74

यह सिंटैक्स विज़ुअल बेसिक सिलेक्ट से है ... केस स्टेटमेंट :

Dim number As Integer = 8
Select Case number
    Case 1 To 5
        Debug.WriteLine("Between 1 and 5, inclusive")
        ' The following is the only Case clause that evaluates to True.
    Case 6, 7, 8
        Debug.WriteLine("Between 6 and 8, inclusive")
    Case Is < 1
        Debug.WriteLine("Equal to 9 or 10")
    Case Else
        Debug.WriteLine("Not between 1 and 10, inclusive")
End Select

आप इस सिंटैक्स का उपयोग C # में नहीं कर सकते। इसके बजाय, आपको अपने पहले उदाहरण से वाक्यविन्यास का उपयोग करना होगा।


49
यह उन कुछ चीजों में से एक है जो मुझे * बेसिक के बारे में याद आती हैं।
1

10
यहां हमारे पास कुछ डिस्प्ले में से एक है जहां विज़ुअल बेसिक बदसूरत नहीं है, और सी # की तुलना में अधिक बहुमुखी है। यह एक मूल्यवान उदाहरण है!
bgmCoder

यह काफी सभ्य है। मुझे आश्चर्य है कि इसे C # 8.0 के साथ क्यों नहीं जोड़ा गया है। बहुत अच्छा होगा।
सिगेक्स

69

C # 7 में (Visual Studio 2017 / .NET फ्रेमवर्क 4.6.2 में डिफ़ॉल्ट रूप से उपलब्ध), रेंज-आधारित स्विचिंग अब स्विच स्टेटमेंट के साथ संभव है और ओपी की समस्या के साथ मदद करेगा।

उदाहरण:

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हैं, लेकिन तुलना (ओं) को उजागर करने के लिए इस उदाहरण में उपयोग किया जाता है।
  • varके एवज में भी इस्तेमाल किया जा सकता है int। उदाहरण के लिए case var n when n >= 7::।

3
यह (पैटर्न मिलान) आम तौर पर सबसे अच्छा अभ्यास होना चाहिए जब आप C # 7.x या इसके बाद के संस्करण का उपयोग कर सकते हैं, क्योंकि यह अन्य उत्तरों की तुलना में बहुत स्पष्ट है।
अंडरकिंगजेलीफ़िश

क्या Enums की सूची के साथ इसे प्राप्त करने का कोई तरीका है? Enums नक्शा करने के लिए कहाँ?
सिगेक्स

32

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

case 1: case 2: case 3:
   break;

लेकिन मैं उस बुरे अंदाज को मानता हूं।


20

.NET फ्रेमवर्क 3.5 को रेंज मिली है:

MSDN से Enumerable.Range

आप इसे "शामिल" और IF स्टेटमेंट के साथ उपयोग कर सकते हैं, जैसे किसी ने कहा कि SWITCH स्टेटमेंट "==" ऑपरेटर का उपयोग करता है।

यहाँ एक उदाहरण है:

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>

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

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

यहां यह बताया गया है कि पुराने कार्यात्मक की तुलना में नए कार्यात्मक आयातित बयान IMHO अधिक शक्तिशाली और सुरुचिपूर्ण कैसे हैं।


3
अच्छा विकल्प। एक बात पर ध्यान दें, हालांकि - Enumerable.Range में तर्क हैं int startऔर int count। आपके उदाहरण न सही वैसे ही काम करते हैं जैसे वे लिखे गए थे। आप इसे ऐसे लिखते हैं जैसे कि दूसरा तर्क है int end। उदाहरण के लिए - Enumerable.Range(11,20)20 की संख्या 11 से शुरू होगी, और 11 से 20 तक संख्या नहीं होगी।
गेब्रियल मैकएडम्स

हालांकि, अगर एक Enum के साथ काम कर रहे हैं, तो कुछ पसंद क्यों नहीं? if (Enumerable.Range (MyEnum.A, MyEnum.M) {DoThing ();} अगर (Enumerable.Range (MyEnum.N, MyEnum.Z) {DoAntotherThing ();}
डेविड होटेल - MSFT

4
ध्यान दें कि Enumerable.Range(11,20).Contains(c)के बराबर है for(int i = 11; i < 21; ++i){ if (i == c) return true; } return false;, तो आप एक बड़ी रेंज यह एक लंबे समय ले जाएगा, जबकि बस का उपयोग कर किया था >और <जल्दी और लगातार समय होगा।
जॉन हैना

एक सुधार: MySwitchWithEnumerableवापसी के बाद voidइस स्थिति के लिए कमजोर डिजाइन है। रिपोर्ट: आपने if-elseस्वतंत्र कथनों की एक श्रृंखला में परिवर्तित कर दिया है - जो इरादे को छुपाता है, जो यह है कि वे पारस्परिक रूप से अनन्य हैं - केवल एक actionको निष्पादित किया जाता है। बदले में bool, बॉडी के साथ if (..) { action(); return true; } else return false;कॉलिंग साइट तब इरादा दिखाता है if (MySwitchWithEnumerable(..)) else (MySwitchWithEnumerable(..));:। यह बेहतर है। हालाँकि, इस सरल मामले के लिए, यह आपके मूल संस्करण पर महत्वपूर्ण सुधार नहीं है।
टूलमेकरसैट

15

यहां देखें पूरा C # 7 समाधान ...

switch (value)
{
   case var s when new[] { 1,2,3 }.Contains(s):
      // Do something
      break;
   case var s when new[] { 4,5,6 }.Contains(s):
      // Do something
      break;
   default:
      // Do the default
      break;
}

यह तार के साथ भी काम करता है ...

switch (mystring)
{
   case var s when new[] { "Alpha","Beta","Gamma" }.Contains(s):
      // Do something
      break;
...
}

इसका मतलब यह होगा कि आप प्रत्येक स्विच स्टेटमेंट के साथ एरे को आवंटित करते हैं, है ना? यदि हम उन्हें निरंतर चर के रूप में लें तो बेहतर नहीं होगा?
MaLiN2223

सुरुचिपूर्ण, लेकिन यह जानना वास्तव में अच्छा होगा कि क्या कंपाइलर इस परिदृश्य का अनुकूलन करता है ताकि बार-बार किए गए इनवोकेशन हर बार सरणी निर्माण के ओवरहेड को उकसाए नहीं; समय से पहले सरणियों को परिभाषित करना एक विकल्प है, लेकिन बहुत से लालित्य को दूर ले जाता है।
mklement0

11

नीचे दिया गया कोड काम नहीं करेगा :

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

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

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

वह कोड जिसे आप Visual Basic में काम करना चाहते हैं, जहाँ आप आसानी से श्रेणी में रख सकते हैं ... कथन के noneविकल्प में switchया if elseसुविधाजनक ब्लॉक, मैं बहुत चरम बिंदु पर सुझाव देना चाहता हूँ, Visual Basic के साथ। Dll और वापस आयात करें। आपके C # प्रोजेक्ट के लिए।

नोट: विज़ुअल बेसिक के बराबर स्विच है Select Case


7

एक अन्य विकल्प दिनचर्या का उपयोग करना होगा। यदि मामले 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()
{
   ...
}

5

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


string s = foo();

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

4
यह बाद में कोड पढ़ने की कोशिश करने वाले किसी अन्य व्यक्ति के लिए एक बड़ा गोत्र बन सकता है
एंड्रयू हैरी

5

सीसीसी अनुक्रमिक सीमाओं का समर्थन करने के लिए सी भाषा के लिए एक विस्तार लागू करता है:

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

संपादित करें : इस सवाल पर बस सी # टैग देखा, इसलिए संभवतः एक जीसीसी जवाब मदद नहीं करता है।


4

C # 7 में अब हमारे पास पैटर्न मिलान है ताकि आप कुछ ऐसा कर सकें:

switch (age)
{
  case 50:
    ageBlock = "the big five-oh";
    break;
  case var testAge when (new List<int>()
      { 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 }).Contains(testAge):
    ageBlock = "octogenarian";
    break;
  case var testAge when ((testAge >= 90) & (testAge <= 99)):
    ageBlock = "nonagenarian";
    break;
  case var testAge when (testAge >= 100):
    ageBlock = "centenarian";
    break;
  default:
    ageBlock = "just old";
    break;
}

3

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

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

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

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

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


ध्यान दें कि व्यवहार में, gotoलगभग हमेशा बचा जा सकता है (हालांकि मैं इसे "भयानक" नहीं मानता - यह एक विशिष्ट, संरचित, भूमिका भर रहा है)। आपके उदाहरण में, क्योंकि आपने केस बॉडी को कार्यों में लपेटा है (अच्छी बात), केस 0 बन सकता है CaseZero(); CaseZeroOrOne(); break;। कोई gotoआवश्यकता नहीं है।
टूलमेकरसेव

लिंक आधा टूटा हुआ है (पुनर्निर्देश, "विजुअल स्टूडियो 2003 सेवानिवृत्त तकनीकी दस्तावेज" )।
पीटर मोर्टेंसन

2

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

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

या आप बस primes का एक सरणी मानचित्र बना सकते हैं और तत्काल परिणाम प्राप्त कर सकते हैं:

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

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

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

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

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

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


आप लैम्ब्डा अभिव्यक्ति या एक प्रतिनिधि के लिए मैप भी कर सकते हैं
कॉनराड फ्रैक्स

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

1

बस बातचीत में जोड़ने के लिए, .NET 4.6.2 का उपयोग करके मैं निम्नलिखित कार्य करने में सक्षम था। मैंने कोड का परीक्षण किया और इसने मेरे लिए काम किया।

आप नीचे की तरह कई "या" कथन भी कर सकते हैं:

            switch (value)
            {
                case string a when a.Contains("text1"):
                    // Do Something
                    break;
                case string b when b.Contains("text3") || b.Contains("text4") || b.Contains("text5"):
                    // Do Something else
                    break;
                default:
                    // Or do this by default
                    break;
            }

आप यह भी देख सकते हैं कि यह किसी सरणी में मान से मेल खाता है या नहीं:

            string[] statuses = { "text3", "text4", "text5"};

            switch (value)
            {
                case string a when a.Contains("text1"):
                    // Do Something
                    break;
                case string b when statuses.Contains(value):                        
                    // Do Something else
                    break;
                default:
                    // Or do this by default
                    break;
            }

क्या यह C # संस्करण पर निर्भर नहीं है, न कि .NET संस्करण पर?
पीटर मोर्टेंसन

1

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

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

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;
    .
    .
    .
}

आप इसे ifइस तरह एक बयान से बदलना चाहते हैं :

// 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
}

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


0

मुझे लगता है कि यह एक C # 7 या उससे ऊपर में बेहतर है।

switch (value)
{
    case var s when new[] { 1,2 }.Contains(s):
    // Do something
     break;

    default:
    // Do the default
    break;
 }

आप सी # स्विच मामले में रेंज की भी जांच कर सकते हैं: स्विच केस: क्या मैं एक नंबर के बजाय एक रेंज का उपयोग कर सकता हूं या यदि आप सी # स्विच केस की मूल बातें समझना चाहते हैं


-5

इसके लिए, आप एक गोटो स्टेटमेंट का उपयोग करेंगे। जैसे कि:

    switch(value){
    case 1:
        goto case 3;
    case 2:
        goto case 3;
    case 3:
        DoCase123();
    //This would work too, but I'm not sure if it's slower
    case 4:
        goto case 5;
    case 5:
        goto case 6;
    case 6:
        goto case 7;
    case 7:
        DoCase4567();
    }

7
@scone गोटो प्रक्रियात्मक प्रोग्रामिंग के एक मूल प्रिंसिपल को तोड़ता है (जिनमें से c ++ और c # अभी भी निहित हैं; वे शुद्ध OO भाषाएँ नहीं हैं (भगवान को धन्यवाद दें))। प्रक्रियात्मक प्रोग्रामिंग में भाषा निर्माणों और विधि कॉलिंग सम्मेलनों (कैसे रनटाइम स्टैक बढ़ता है और सिकुड़ता है) द्वारा निर्धारित तर्क का एक अच्छी तरह से परिभाषित प्रवाह है। गोटो बयान मूल रूप से चारों ओर मनमानी कूदने की अनुमति देकर इस प्रवाह को दरकिनार कर देता है।
samis

1
मैं यह नहीं कह रहा हूं कि यह अच्छी शैली है, दृढ़ है, लेकिन यह वही करता है जो मूल प्रश्न पूछ रहा था।
स्कोन

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

गोटो के खराब होने का एकमात्र कारण यह है कि कुछ लोगों को तर्क प्रवाह का पालन करना कठिन लगता है। .Net MSIL (असेंबल्ड ऑब्जेक्ट कोड) सभी तेजी से गोटो का उपयोग करता है, लेकिन अगर .Net कोड लिखा जा सकता है और उनके बिना परफॉर्मर के रूप में लिखा जा सकता है तो उनका उपयोग न करना बेहतर है और इसलिए आप @ जैसे लोगों से नहीं मिलते। टूलमेकरसेव का कृपालु उत्तर।
डायनामलिनक

@wchoward - कृपया मेरे उत्तर को अधिक ध्यान से पढ़ें। मेरी शिकायत सिर्फ गोटो के इस्तेमाल को लेकर नहीं है । मैंने आपत्ति जताई क्योंकि प्रश्न में ऐसा कोड दिखाया गया है जो पहले से ही काम कर रहा है , और यह उत्तर क) काम करने वाले कोड को लेता है और इसे अधिक क्रिया करता है, और कम-अच्छी तरह से संरचित, बिना किसी लाभ के , ख) प्रश्न का उत्तर नहीं देता है।
टूलमेकर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.