C # पूर्व कोड के बिना {} कोड ब्लॉक की अनुमति क्यों देता है?


86

क्यों सी # अनुमति नहीं है एक पूर्ववर्ती बयान के बिना कोड ब्लॉक (जैसे if, else, for, while)?

void Main()
{
    {   // any sense in this?
        Console.Write("foo");
    }
}

70
क्या कोई कारण नहीं होना चाहिए ?
जैमीक

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

8
+1 प्रश्न पर्याप्त निर्दोष लगता है, लेकिन जवाब ने मुझे वास्तव में कुछ मूल्यवान सिखाया है
निकोलस78

7
@ आकाश: बिना पूछे क्यों, हम कभी बेहतर नहीं होंगे।
रिचर्ड

7
@ आकाश: यह एक उच्च-ब्राइट अभिजात वर्ग के रवैये की तरह लगता है। लोगों के पास हमेशा सवाल होते हैं, और यदि कोई कारण नहीं है, तो एसओ होने का कोई मतलब नहीं है। यह साइट हमारे लोगों की तात्कालिक समस्याओं (हालांकि ऐसा होता है) को हल करने के लिए बहुत अधिक नहीं है, लेकिन उन सवालों और जवाबों का भंडार प्रदान करने में मदद करेगी जो हम सभी को बेहतर प्रोग्रामर बनने में मदद करेंगे। तो क्यों पूछ के लिए है! :-)
रिचर्ड

जवाबों:


90

आपके द्वारा दिए गए संदर्भ में, कोई महत्व नहीं है। कंसोल के लिए एक निरंतर स्ट्रिंग लिखना प्रोग्राम प्रवाह में कहीं भी उसी तरह काम करने वाला है। 1

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


1 जब तक, निश्चित रूप से, आप अजीब होने की कोशिश करने का फैसला करते हैं और अपनी Consoleकक्षा बनाते हैं , एक ऐसी Write()विधि के साथ जो पूरी तरह से अप्रत्याशित कुछ करती है।


24
अन्य भाषाओं में: आमतौर पर, लेकिन हमेशा नहीं। जावास्क्रिप्ट एक उल्लेखनीय अपवाद है; किसी विशेष ब्लॉक में स्थानीय चर घोषित करने से वैरिएबल ब्लॉक में नहीं आता है।
एरिक लिपर्ट

@ EricLippert: C # में, किसी ब्लॉक के भीतर एक वैरिएबल घोषित करने से वैरिएबल रन-टाइम के परिप्रेक्ष्य से स्कोप हो सकता है? मैं जो बता सकता हूं, वैरिएबल के जीवनकाल अक्सर स्कूपिंग ब्लॉक से बंधे नहीं होते हैं, एक तथ्य जो मिश्रित भाषा की परियोजनाओं में अवलोकनीय है यदि पहली बात एक लूप में एक चर के साथ किया जाता है, इसे outएक इंटरफ़ेस कार्यान्वयन के लिए एक पैरामीटर के रूप में पारित किया जाता है किसी अन्य भाषा में, और उस कार्यान्वयन को लिखने से पहले चर को पढ़ता है।
सुपरकैट

और C ++ में, GC के बजाय RAII के कारण, यह कहीं अधिक उपयोगी है।
डेडुप्लिकेटर

C ++ में, यह एक try / कैच ब्लॉक की तरह काम करता है, इसलिए जब आप उस दायरे को छोड़ देते हैं, तो उस दायरे के भीतर घोषित चर और वर्ग ढेर हो जाते हैं। यह नाम टकराव को रोकने में मदद करता है और फ़ंक्शन की मेमोरी फ़ुटप्रिंट को कम करता है। यह उन चरों को भी कोड संपादक के ऑटो-पूर्ति से हटा देता है। अक्सर मुझे लगता है कि कोशिश / पकड़ ब्लॉक अधिक उपयोगी है।
किट 10

144

{ ... }स्थानीय चर के लिए एक नया दायरे को शुरू करने से कम से कम पक्ष प्रभाव है।

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


6
यह पढ़ने के लायक है blogs.msdn.com/b/ericlippert/archive/2009/08/03/…
Dan Diplo

6
यदि आपको अपने मामलों में स्कोप की आवश्यकता है, तो वे बहुत बड़े हैं! निकालने की विधि।
जय बज्जुइ

20
@ जय बज़ुजी, सिर्फ इसलिए कि मैं एक से अधिक मामलों में एक ही नाम के साथ एक स्थानीय चर रखना चाहता हूं इसका मतलब यह नहीं है कि उन्हें बहुत बड़ा होना चाहिए। आप बस विशाल निष्कर्ष पर कूद रहे हैं ... :)
जोआ एंजेलो

आपके महान जवाब बिल्ला को बधाई! :)
BoltClock

1
@BoltClock, धन्यवाद, मुझे अभी {}उन सोने के बैज को रखने के बारे में कुछ और सवालों की जरूरत है ... :)
जोआ एंजेलो

56

यह C # की इतनी अधिक विशेषता नहीं है क्योंकि यह कई C वाक्यविन्यास भाषाओं का तार्किक साइड-इफेक्ट है जो स्कोप को परिभाषित करने के लिए ब्रेसिज़ का उपयोग करता है

आपके उदाहरण में ब्रेसिज़ का कोई प्रभाव नहीं है, लेकिन निम्नलिखित कोड में वे दायरे को परिभाषित करते हैं, और इसलिए एक चर की दृश्यता:

यह अनुमति दी जाती है क्योंकि मैं पहले ब्लॉक में दायरे से बाहर हो जाता है और अगले में फिर से परिभाषित होता है:

{
    {
        int i = 0;
    }

    {
        int i = 0;
    }
}

यह अनुमति नहीं है क्योंकि मैं दायरे से बाहर हो गया हूं और अब बाहरी दायरे में दिखाई नहीं देता:

{
    {
        int i = 0;
    }

    i = 1;
}

और आगे और आगे।


1
मैंने अंग्रेजी के विभिन्न स्वादों में ब्रैकेट नामकरण में असमानताओं के बारे में पढ़ा है, लेकिन किस स्वाद में {}इसे कोष्ठक के रूप में जाना जाता है?
BoltClock

अच्छा प्रश्न! मुझे लगता है कि मेरे एक संरक्षक ने एक दशक पहले मेरे दिमाग में इसे लगाया था। मुझे शायद उन्हें 'कर्ली ब्रैकेट्स' या 'ब्रेसेस' कहना चाहिए। प्रत्येक अपने स्वयं के ... en.wikipedia.org/wiki/…
क्रिस वालिस

10
मेरे वकताब में '(' = कोष्ठक, '{' = कंस, '' '= वर्ग कोष्ठक

रुको, मैं उन्हें एक घुंघराले ब्रैकेट कहूंगा, और विकिपीडिया में यह नामकरण शामिल है। ऑक्सफोर्ड इंग्लिश डिक्शनरी ब्रैकेट के इस उपयोग को परिभाषित करती है: One of two marks of the form [ ] or ( ), and in mathematical use also {}, used for enclosing a word or number of words, a portion of a mathematical formula, or the like, so as to separate it from the context; किसी भी मामले में वे कोष्ठक नहीं हैं, लेकिन 'घुंघराले ब्रैकेट' ठीक लगते हैं।
dumbledad

IME, "घुंघराले ब्रेसिज़" और "चौकोर कोष्ठक"।
cp.engr

18

मैं {}एक बयान के रूप में मानता हूं जिसमें कई कथन हो सकते हैं।

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

if (true) Console.Write("FooBar");

यह भी काम करेगा:

if (true)
{
  Console.Write("Foo");
  Console.Write("Bar");
}

अगर मैं गलत नहीं हूँ तो इसे एक ब्लॉक स्टेटमेंट कहा जाता है।

चूंकि {}इसमें अन्य कथन हो सकते हैं, इसलिए इसमें अन्य भी हो सकते हैं {}। एक चर का दायरा अभिभावक {}(ब्लॉक स्टेटमेंट) द्वारा परिभाषित किया गया है ।

मैं जिस बिंदु को बनाने की कोशिश कर रहा हूं वह {}यह है कि यह सिर्फ एक बयान है, इसलिए इसे एक या कुछ भी आवश्यकता नहीं है ...


+1 यह वही है जो सी-स्टाइल भाषाओं में ब्रेसिज़ हैं - एक तथाकथित "यौगिक स्टेटमेंट"।
माइकल एकस्ट्रैंड

12

C- वाक्यविन्यास भाषाओं में सामान्य नियम यह है कि "किसी भी चीज़ { }को एक कथन के रूप में माना जाना चाहिए, और यह वह जगह जा सकती है जहाँ एक एकल कथन हो सकता है"

  • एक के बाद if
  • एक के बाद for, whileया do
  • कहीं भी कोड में

सभी इरादों और उद्देश्यों के लिए, यह भाषा व्याकरण के रूप में शामिल है:

     <statement> :== <definition of valid statement> | "{" <statement-list> "}"
<statement-list> :== <statement> | <statement-list> <statement>

यही है, "एक बयान (विभिन्न चीजों से बना हो सकता है ) या एक उद्घाटन ब्रेस के बाद, एक कथन सूची (जिसमें एक या एक से अधिक कथन शामिल हो सकते हैं), उसके बाद एक बंद ब्रेस"। IE "एक { }ब्लॉक किसी भी जगह, कहीं भी बयान कर सकता है"। कोड के बीच में शामिल है।

{ }ब्लॉक को कहीं भी अनुमति नहीं देने से एक भी कथन वास्तव में भाषा की परिभाषा को और अधिक जटिल बना सकता है


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

1

क्योंकि C ++ (और जावा) ने पूर्ववर्ती कथन के बिना कोड ब्लॉक की अनुमति दी थी।

C ++ ने उन्हें अनुमति दी क्योंकि C ने किया था।

आप यह कह सकते हैं कि यह सब इस तथ्य से कम है कि संयुक्त राज्य अमेरिका की कार्यक्रम भाषा (C आधारित) डिज़ाइन यूरोपीय कार्यक्रम भाषा ( Modula-2 आधारित) डिज़ाइन के बजाय जीती है ।

(नियंत्रण कथन एक कथन पर कार्य करते हैं, कथन नए कथन बनाने के लिए समूह हो सकते हैं)


क्या आपका मतलब है Module2, या Modula2?
रिचर्ड ईव

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


0

1 क्योंकि ... इसके बयान के स्कोप क्षेत्र को बनाए रखें .. या फ़ंक्शन, यह वास्तव में बड़े कोड के लिए उपयोगी है।

{
    {
        // Here this 'i' is we can use for this scope only and out side of this scope we can't get this 'i' variable.

        int i = 0;
    }

    {
        int i = 0;
    }
}

यहां छवि विवरण दर्ज करें


0

आपने "क्यों" C # कथन के बिना कोड ब्लॉक की अनुमति देता है। प्रश्न "क्यों" की व्याख्या "इस निर्माण के संभावित लाभ क्या होंगे?" के रूप में भी की जा सकती है।

व्यक्तिगत रूप से, मैं C # में स्टेटमेंट-कम कोड ब्लॉक का उपयोग करता हूं, जहां अन्य डेवलपर्स के लिए पठनीयता में बहुत सुधार होता है, जबकि यह ध्यान में रखते हुए कि कोड ब्लॉक स्थानीय चर के दायरे को सीमित करता है। उदाहरण के लिए, निम्नलिखित कोड स्निपेट पर विचार करें, जो अतिरिक्त कोड ब्लॉक के लिए धन्यवाद पढ़ना बहुत आसान है:

OrgUnit world = new OrgUnit() { Name = "World" };
{
    OrgUnit europe = new OrgUnit() { Name = "Europe" };
    world.SubUnits.Add(europe);
    {
        OrgUnit germany = new OrgUnit() { Name = "Germany" };
        europe.SubUnits.Add(germany);

        //...etc.
    }
}
//...commit structure to DB here

मुझे पता है कि प्रत्येक संरचना स्तर के लिए विधियों का उपयोग करके इसे और अधिक सुरुचिपूर्ण ढंग से हल किया जा सकता है। लेकिन फिर, ध्यान रखें कि नमूना डेटा सीडर्स जैसी चीजों को आमतौर पर जल्दी करने की आवश्यकता होती है।

तो भले ही ऊपर दिए गए कोड को रैखिक रूप से निष्पादित किया जाता है, कोड संरचना वस्तुओं की "वास्तविक दुनिया" संरचना का प्रतिनिधित्व करती है, इस प्रकार अन्य डेवलपर्स के लिए समझना, बनाए रखना और विस्तारित करना आसान होता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.