सवाल बयान के बाद परिवर्तनीय घोषणाएं


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

निम्नलिखित कोड अवैध है

if (true)
    int i = 7;

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

if (true)
{
    int i = 7;
}

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


58
2018-03-22 23:54


मूल




जवाब:


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

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

में if बयान शरीर को होना है एम्बेडेड बयान, जो बताता है कि कोड का पहला संस्करण क्यों काम नहीं करता है। यहां वाक्यविन्यास है if विनिर्देशन से (धारा 8.7.1):

अगर ( बूलियन अभिव्यक्ति ) एम्बेडेड बयान
  अगर ( बूलियन अभिव्यक्ति ) एम्बेडेड बयान अन्य एम्बेडेड बयान

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


78
2018-03-23 00:07





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

यहां एरिक लिपर्ट का हिस्सा सी # कंपाइलर के बारे में कहना है यह SO जवाब नाम संकल्प के बारे में:

... सी # एक "अनुमान नहीं है कि उपयोगकर्ता क्या है   मतलब "भाषा ... द्वारा संकलक   सबसे अच्छा अगर डिजाइन जोर से शिकायत करता है   मैच ऐसा कुछ है जो काम नहीं करता है


27
2018-03-22 23:57



मैं मानता हूं, इस तरह से एक चर घोषित करने के लिए यह बिल्कुल समझ में नहीं आता है। फिर भी दूसरे उदाहरण में पूरी तरह से बेकार परिवर्तनीय घोषणा ठीक है। न तो मूल्य है। क्या यह केवल ब्रैकेटिंग का मामला है, और कुछ नहीं? (मैं उस रास्ते से, साथ रह सकता हूं।) - Anthony Pegram
हाँ। जब आप ब्रैकेट्स को शामिल करते हैं तो आपके इरादे संकलक के लिए बिल्कुल स्पष्ट होते हैं, इसलिए यह इसकी अनुमति देगा। सी # कंपाइलर इसे ब्रैकेट के बिना अनुमति नहीं देगा, क्योंकि यह स्पष्ट नहीं है कि आपका वास्तविक इरादा बेकार चर घोषित करना है। - Zach Johnson
लेकिन दूसरा मूल्य का बहुत अच्छा हो सकता है - अगर, उदाहरण के लिए, मूल्य को उस विधि से पुनर्प्राप्त किया जा रहा है जिसमें साइड इफेक्ट्स हैं। - Andrew Medico
उस पर एरिक की पोस्ट के लिंक के लिए धन्यवाद। अब मुझे पता है कि हाल ही में एक ब्लॉग श्रृंखला की उत्पत्ति हुई थी। - Anthony Pegram


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

दूसरा मामला धारा 8.0 की शुरुआत में सीधे सी # भाषा विनिर्देश में बुलाया जाता है

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

उदाहरण कोड

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

9
2018-03-23 00:03



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


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

पहले: इससे त्रुटि हुई:

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

0
2017-07-26 07:32