2010-03-22 20 views
56

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

निम्नलिखित कोड गैरकानूनी है

if (true) 
    int i = 7; 

हालांकि, अगर आप लपेट कि कोष्ठक में, यह सब कानूनी है।

if (true) 
{ 
    int i = 7; 
} 

कोड का कोई भी टुकड़ा उपयोगी नहीं है। फिर भी दूसरा एक ठीक है। इस व्यवहार के लिए विशेष रूप से स्पष्टीकरण क्या है?

उत्तर

76

C# language specification बयान के तीन प्रकार (देखें अध्याय 8 में भेद पर सी # भाषा विनिर्देश में सीधे बाहर कहा जाता है अधिक जानकारी के लिए)। सामान्य तौर पर आप इन बयानों हो सकता है:

  • लेबल बयान - मेरा अनुमान है कि यह पुराने जमाने goto बयान के लिए है
  • घोषणा बयान - एक चर घोषणा
  • होगा जो एम्बेडेड-स्टेटमेंट - जिसमें शेष शेष बयान

0 मेंबयान शरीर को एम्बेडेड-स्टेटमेंट होना चाहिए, जो बताता है कि कोड का पहला संस्करण क्यों काम नहीं करता है। विनिर्देशन से if का सिंटैक्स यहां है (खंड 8.7।1):

if (boolean-expression) embedded-statement
if (boolean-expression) embedded-statement else embedded-statement

एक चर घोषणा, घोषणा बयान है तो यह शरीर में प्रकट नहीं कर सकते हैं। यदि आप ब्रैकेट में घोषणा को संलग्न करते हैं, तो आपको एक स्टेटमेंट ब्लॉक मिलेगा, जो एम्बेडेड-स्टेटमेंट है (और इसलिए यह उस स्थिति में दिखाई दे सकता है)।

27

जब आप ब्रैकेट्स को शामिल नहीं करते हैं, तो यह अगली पंक्ति को निष्पादित करता है जैसे कि यह ब्रैकेट से घिरा हुआ था। चूंकि यह उस पंक्ति में एक चर घोषित करने के लिए ज्यादा समझ नहीं लेता है (आप इसे कभी भी उपयोग नहीं कर पाएंगे), सी # कंपाइलर आपको बिना किसी अज्ञात रूप से इसे करने से रोकने के लिए अनुमति देगा (जो सूक्ष्म बग पेश कर सकता है)।

यहाँ एरिक Lippert का हिस्सा नाम संकल्प के बारे में this SO answer पर सी # संकलक के बारे में क्या कहना है है:

...C# is not a "guess what the user meant" language...the compiler by design complains loudly if the best match is something that doesn't work

+1

मैं मानता हूँ में जोड़ा गया कोष्ठक, यह बिल्कुल मतलब नहीं है एक घोषित करने के लिए इस तरह से परिवर्तनीय। फिर भी दूसरे उदाहरण में पूरी तरह से बेकार परिवर्तनीय घोषणा ठीक है। न तो मूल्य है। क्या यह केवल ब्रैकेटिंग का मामला है, और कुछ नहीं? (मैं उस रास्ते से, साथ रह सकता हूं।) –

+3

हां। जब आप ब्रैकेट्स को शामिल करते हैं तो आपके इरादे संकलक के लिए बिल्कुल स्पष्ट होते हैं, इसलिए यह इसकी अनुमति देगा। सी # कंपाइलर इसे ब्रैकेट के बिना अनुमति नहीं देगा, क्योंकि यह स्पष्ट नहीं है कि आपका वास्तविक इरादा बेकार चर घोषित करना है। –

+0

लेकिन दूसरा मूल्य का बहुत अच्छा हो सकता है - यदि, उदाहरण के लिए, मूल्य को उस विधि से पुनर्प्राप्त किया जा रहा है जिसमें साइड इफेक्ट्स हैं। –

9

सभी compilers आप कोड है कि बेकार या बेहद कम उपयोग की है संकलित करने के लिए अनुमति देगा। ऐसे कई तरीके हैं जो डेवलपर भाषा का उपयोग किसी भी उपयोग के साथ बनाने के लिए कर सकते हैं। कंपाइलर पकड़ने के बाद उनमें से सभी बहुत अधिक प्रयास हैं और आम तौर पर इसके लायक नहीं हैं।

दूसरे मामले खंड की शुरुआत 8,0

The example results in a compile-time error because an if statement requires an embedded-statement rather than a statement for its if branch. If this code were permitted, then the variable i would be declared, but it could never be used. Note, however, that by placing i’s declaration in a block, the example is valid.

उदाहरण कोड

void F(bool b) { 
    if (b) 
     int i = 44; 
} 
+0

इनपुट के लिए धन्यवाद, बहुत फायदेमंद। –

0

अगर किसी अन्य भाग पर बंद होने और खोलने वाले ब्रेसिज़ को जोड़ने में मेरी मदद की गई तो मैंने उन्हें जोड़ने से पहले जो किया था उसके विरोध में नीचे किया है;

से पहले:

protected void btnAdd_Click(object sender, EventArgs e) 
    { 
     if (btnAdd.Text == "ADD") 
     { 

      CATEGORY cat = new CATEGORY 
      { 

       NAME = tbxCategory.Text.Trim(), 
       TOTALSALEVALUE = tbxSaleValue.Text.Trim(), 
       PROFIT = tbxProfit.Text.Trim() 

      }; 
      dm.AddCategory(cat, tbxCategory.Text.Trim()); 
     } 
     else 
     // missing brackets - this was causing the error 
      var c = getCategory(); 
      c.NAME = tbxCategory.Text.Trim(); 
      c.TOTALSALEVALUE = tbxSaleValue.Text.Trim(); 
      c.PROFIT = tbxProfit.Text.Trim(); 
      dm.UpdateCategory(c); 

     btnSearchCat_Click(btnSearchCat, e); 
    } 

के बाद: इस त्रुटि के कारण किसी और शाखा

protected void btnAdd_Click(object sender, EventArgs e) 
    { 
     if (btnAdd.Text == "ADD") 
     { 

      CATEGORY cat = new CATEGORY 
      { 

       NAME = tbxCategory.Text.Trim(), 
       TOTALSALEVALUE = tbxSaleValue.Text.Trim(), 
       PROFIT = tbxProfit.Text.Trim() 

      }; 
      dm.AddCategory(cat, tbxCategory.Text.Trim()); 
     } 
     else 
     { 
      var c = getCategory(); 
      c.NAME = tbxCategory.Text.Trim(); 
      c.TOTALSALEVALUE = tbxSaleValue.Text.Trim(); 
      c.PROFIT = tbxProfit.Text.Trim(); 
      dm.UpdateCategory(c); 
     } 
     btnSearchCat_Click(btnSearchCat, e); 
    } 
संबंधित मुद्दे