2008-10-21 16 views
90

क्यों यह है कि सी # स्विच स्टेटमेंट में, कई मामलों में उपयोग किए जाने वाले चर के लिए, आप केवल इसे पहले मामले में घोषित करते हैं?सी # स्विच स्टेटमेंट में परिवर्तनीय घोषणा

उदाहरण के लिए, निम्नलिखित त्रुटि फेंकता है "एक स्थानीय चर नाम 'चर' पहले से ही इस दायरे में परिभाषित किया गया है"।

switch (Type) 
{ 
    case Type.A: 
      string variable = "x"; 
       break; 
    case Type.B: 
      string variable = "y"; 
       break; 
} 

हालांकि, तर्क के अनुसार, प्रारंभिक घोषणा करता है, तो प्रकार Type.B है हिट नहीं किया जाना चाहिए। एक स्विच स्टेटमेंट के भीतर सभी चर एक एकल दायरे में मौजूद हैं, और क्या वे किसी भी तर्क को संसाधित करने से पहले बनाए/आवंटित किए जाते हैं?

+0

वास्तव में बदसूरत बातों में break का उपयोग नहीं कर सबसे उपयोगी है लोग ऐसा करते हैं कि: 'स्विच (प्रकार) {मामले टाइप.ए: स्ट्रिंग वेरिएबल = "एक्स"; टूटना; केस टाइप.बी: परिवर्तनीय = "वाई"; टूटना; } ' – giammin

+0

@giammin: कृपया विस्तृत करें। – zazkapulsk

+1

@zazkapulsk आपको पहले एक चर घोषित करना चाहिए और फिर स्विच में इसका उपयोग करना चाहिए: 'string variable = null; स्विच (प्रकार) {केस टाइप.ए: परिवर्तनीय = "एक्स"; टूटना; केस टाइप.बी: परिवर्तनीय = "वाई"; टूटना; } ' – giammin

उत्तर

39

मुझे विश्वास है कि इसे चर के समग्र दायरे से करना है, यह एक ब्लॉक स्तर का दायरा है जिसे स्विच स्तर पर परिभाषित किया गया है।

व्यक्तिगत रूप से यदि आप वास्तव में किसी भी लाभ के लिए अपने उदाहरण में स्विच के अंदर कुछ मूल्य निर्धारित कर रहे हैं, तो आप इसे स्विच के बाहर भी घोषित करना चाहते हैं।

+35

ब्रेसिज़ का पालन करें। एक चर केवल अंतर्निहित ब्रेसिज़ के अंदर मौजूद होता है जिसमें चर को पहली बार घोषित किया जाता है। –

28

हां, दायरा संपूर्ण स्विच ब्लॉक है - दुर्भाग्यवश, आईएमओ। हालांकि, आप एक छोटे से दायरे को बनाने के लिए, हमेशा एक ही मामले में ब्रेसिज़ जोड़ सकते हैं। चाहे वे बनाए गए/आवंटित किए गए हों - स्टैक फ्रेम में एक विधि में सभी स्थानीय चर के लिए पर्याप्त स्थान है (कैप्चर किए गए चर की जटिलताओं को छोड़कर)। ऐसा नहीं है कि विधि के निष्पादन के दौरान उस स्थान आवंटित किया गया है।

+3

सभी उचित सम्मान के साथ, आपकी स्केटीनेस, कृपया स्विच केस ब्लॉक में स्कोप जोड़ने की अनुशंसा न करें। यदि आपको उस ब्लॉक के लिए एक नया दायरा चाहिए, तो आप ब्लॉक में बहुत अधिक कर रहे हैं। इसके बजाए, मेरा सुझाव है कि आप प्रसंस्करण की सिफारिश करें कि फ़ंक्शन कॉल पर धक्का दिया जाए। – Randolpho

+21

@Randolpho: मुझे लगता है कि बनाने के लिए यह एक सामान्य बयान है। यह आसानी से केवल तीन या चार लाइनों हो सकता है, लेकिन दो या तीन स्थानीय चर को प्रभावित कर सकता है - इसके लिए एक विधि कॉल में दोबारा प्रतिक्रिया करने के लिए दर्द होना पर्याप्त है। –

+4

सहमत हुए, मैं इस मुद्दे में एक से अधिक बार कूद गया, और यह दो या तीन लाइनों के प्रसंस्करण तर्क के लिए था ... इसे एक अलग विधि में रखना सिर्फ दर्द है। – Philippe

9

क्योंकि उनका दायरा स्विच ब्लॉक पर है। C# Language Specification निम्नलिखित बताता है:

एक स्थानीय चर या स्विच ब्लॉक में घोषित निरंतर का दायरा स्विच ब्लॉक है।

0

प्रारंभिक स्थिति मामले में होती है, लेकिन घोषणा प्रभावी ढंग से दायरे के शीर्ष पर की जाती है। (छद्म-कोड)

switch (Type) 
{ 
string variable; 

    case Type.A: 
      variable = "x"; 
       break; 
    case Type.B: 
      variable = "y"; 
       break; 
} 
+12

मुझे यकीन है कि यह कोड –

+3

@Jim काम नहीं करता है, हां, मुझे पता है कि कोड काम नहीं करता है - यही कारण है कि मैंने इसे "छद्म कोड" के रूप में संदर्भित किया है, लेकिन यह " प्रभावी ढंग से "किया। –

+0

काफी नहीं। इस बात पर विचार करें कि यदि आप 'ब्रेक' को हटाते हैं जैसे आप '' स्ट्रिंग चर = "x"; परिवर्तनीय = "वाई"; '' यह सभी उद्देश्यों और उद्देश्यों के लिए एक प्रक्रियात्मक 'गोटो:' है। सही कोड '' स्ट्रिंग myVar जैसे कुछ होना चाहिए; स्विच (myValue) { केस MyEnum.A: myVar = "x"; टूटना; केस MyEnum.B: myVar = "वाई"; टूटना; } '' – percebus

0

चर सी # संकलक में गुंजाइश का हिस्सा है। हालांकि, CIL में उसी तरह का दायरा मौजूद नहीं है। वास्तविक सृजन/प्रारंभिकरण के लिए ... .NET मेमोरी मॉडल संकलक को थोड़ा सा पढ़ता/लिखता है जब तक कि सरल नियमों का पालन नहीं किया जाता है जब तक वेरिएबल को volatile के रूप में चिह्नित नहीं किया जाता है।

168

यदि आप चाहते हैं एक चर एक विशेष मामले के दायरे वाला, बस अपनी ही ब्लॉक में मामला बंद:

switch (Type) 
{ 
    case Type.A: 
    { 
     string variable = "x"; 
     /* Do other stuff with variable */ 
    } 
    break; 

    case Type.B: 
    { 
     string variable = "y"; 
     /* Do other stuff with variable */ 
    } 
    break; 
} 
+2

एक नोट: यह ब्रेस काम नहीं करेगा अगर ब्रेस केवल पहला ब्लॉक संलग्न है, लेकिन दूसरा नहीं। ऐसे मामले में दूसरा «परिवर्तनीय» अभी भी त्रुटि जारी कर रहा है, हालांकि स्कॉप्स अलग हैं। एक बग की तरह लग रहा है। –

+2

@ हाय-एंजेल: यह एक बग नहीं है। एक ही नाम वाले एकाधिक स्थानीय चर को ब्लॉक या उसके घोंसले वाले ब्लॉक के अंदर घोषित नहीं किया जा सकता है। असल में, एक घोंसला वाले ब्लॉक में 'स्थानीय' वेरिएबल होते हैं जिन्हें संलग्न ब्लॉक में घोषित किया जाता है - भले ही घोषणा फाइल में बाद में हो। यह एक स्विच स्टेटमेंट के अलावा संरचनाओं के लिए भी सच है। देखें 3।सी # भाषा spec –

+0

मुझे लगता है कि मुझे यह मिला है: यदि चर में अवरोध मौजूद है, तो मैं नेस्टेड ब्लॉक में वही नाम का उपयोग नहीं कर सकता है, भले ही नेस्टेड ब्लॉक वैरिएबल की घोषणा से अधिक रहता है। यह तर्कहीन है, और एक बग होना चाहिए, लेकिन एक दस्तावेज़ में उत्कीर्ण एक बग एक विशेषता बन जाता है ☺ –

-1

"मेरे Daaaaays में ..."

swicth एक बहुत आदिम है प्रक्रियात्मक कार्यान्वयन जो C की उम्र से ही आसपास है (C++ से पहले)।

पूरे switch एक ब्लॉक कि रूप में कार्य करता है एक गुंजाइश निहित GOTO: (इसलिए प्रत्येक case में :)। यदि आप कुछ असेंबलर कक्षाएं लेते हैं, तो यह परिचित प्रतीत हो सकता है।

यही वजह है कि switch उपयोग जब Enum के साथ संयोजन और हर एक case

तरह
switch(mood) 
{ 
    case Mood.BORED: 
    case Mood.HAPPY: 
     drink(oBeer) // will drink if bored OR happy 
break; 

    case Mood.SAD: // unnecessary but proofs a concept 
    default: 
     drink(oCoffee) 
break; 
} 
संबंधित मुद्दे