2010-07-30 10 views
8

निम्नलिखित कोड नमूना पर विचार करें:सी # गुंजाइश सवाल

      // line # 
{      // 1 
         // 2 
    {     // 3 
     double test = 0; // 4 
    }     // 5 
         // 6 
    double test = 0;  // 7 
}      // 8 

यह त्रुटि

एक स्थानीय चर 'परीक्षण' नामक इस दायरे में घोषित नहीं किया जा सकता देता है क्योंकि यह करने के लिए एक अलग अर्थ देना होगा 'टेस्ट', जिसे पहले से ही किसी अन्य बच्चे को

को इंगित करने के लिए पहले से ही 'बच्चे' दायरे में उपयोग किया जाता है लेकिन मुझे समझ में नहीं आता क्यों? बाहरी टेस्ट वैरिएबल लाइन 7 में शुरू होता है और लाइन 2 में नहीं, तो लाइन 5 पर समाप्त होने वाले दायरे के साथ लाइन 4 पर परीक्षण नामक दूसरा चर घोषित करने की समस्या कहां है?

+7

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

+1

http://blogs.msdn.com/b/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx – LukeH

+0

यह मुझे लगता है कि 'सफलता की पिट' का एक उदाहरण है .NET के विभिन्न हिस्सों के डिजाइन में दर्शन (रेफरी http://blogs.msdn.com/b/brada/archive/2003/10/02/50420.aspx) – AakashM

उत्तर

3

यह अक्सर पूछे जाने वाले प्रश्न है; यह भी देखें:

Lambda variable scope

C# going nuts when I declare variables with the same name as the ones in a lambda

C# variable scoping: 'x' cannot be declared in this scope because it would give a different meaning to 'x'

Variable scope confusion in C#

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

उदाहरण के लिए:

class C 
{ 
    int x; 
    void M() 
    { 
     int x; 
    } 
} 

पूरी तरह से कानूनी। ध्यान दें कि बाहरी x का दायरा ओवरलैप करता है आंतरिक x का दायरा। यह दोनों में दायरे में समान नाम के साथ ओवरलैपिंग स्कोप रखने के लिए अवैध है।

यह कानूनी नहीं है:

class C 
{ 
    int x; 
    void M() 
    { 
     Console.WriteLine(x); // this.x 
     { 
      int x; 
     } 
    } 
} 

फिर, दोनों एक एक्स अतिव्यापी के साथ दो स्कोप पूरी तरह से कानूनी है। जो है, एम(), शामिल है जो एम

कार्यक्रम के भीतरी ब्लॉक के बाहरी ब्लॉक के भीतर - क्या गैर-कानूनी है कि सरल नाम एक्स एक ही ब्लॉक में दो मतलब दो अलग चर इस्तेमाल किया जाता है जहां एक ही सरल नाम इस्तेमाल किया एक ही ब्लॉक में दो अलग बातें मतलब करने के लिए कर रहे हैं भ्रमित और बग है प्रवण और इसलिए सी # में अवैध हैं।

अधिक जानकारी के लिए इस विषय पर मेरे लेख पढ़ें:

http://blogs.msdn.com/b/ericlippert/archive/tags/simple+names/

+0

इस विस्तृत उत्तर के लिए आपको बहुत बहुत धन्यवाद! –

10

चर ब्लॉक वे घोषित किये गए हैं भीतर scoped रहे हैं, यह बात नहीं क्या लाइन वे में हैं नहीं करता है।

सी # भाषा कल्पना में scopes बारे में पढ़ें।

कल्पना से:

एक स्थानीय चर एक स्थानीय-चर-घोषणा (Section 8.5.1) में घोषित की गुंजाइश ब्लॉक जिसमें घोषणा होती है।

और:

कार्यक्षेत्र नेस्ट किया जा सकता है, और एक आंतरिक गुंजाइश एक बाहरी दायरे से एक नाम का अर्थ redeclare सकता है। (यह नहीं है, तथापि, प्रतिबंध धारा 3.3 द्वारा लगाए गए कि एक नेस्टेड ब्लॉक यह एक संलग्न ब्लॉक में एक स्थानीय चर के रूप में एक ही नाम के साथ एक स्थानीय चर घोषित करने के लिए संभव नहीं है के भीतर हटाने करता है।)

+0

स्पष्टीकरण के लिए धन्यवाद और लिंक, ओडेड/रॉबर्ट! बीटीडब्लू यहां लिंक किए गए पेज से संबंधित उद्धरण है http://msdn.microsoft.com/en-us/library/aa691132%28VS.71%29.aspx: "स्कॉप्स को घोंसला जा सकता है, और एक आंतरिक दायरा फिर से शुरू हो सकता है बाहरी क्षेत्र से किसी नाम का अर्थ। (हालांकि, यह धारा 3.3 द्वारा लगाए गए प्रतिबंध को नहीं हटाता है, जो एक नेस्टेड ब्लॉक के भीतर एक स्थानीय चर के रूप में एक स्थानीय चर के रूप में एक स्थानीय चर के रूप में घोषित करना संभव नहीं है।) " –

+0

@ stefan.at.wpf - सच। इस जानकारी को शामिल करने के लिए अद्यतन उत्तर दिया गया। – Oded

0

+1 , मैं आपसे सहमत हूं, लेकिन यह नहीं है कि कल्पना कैसे लिखी गई है। यह मुझे यकीन है कि कंपाइलर लिखना आसान बनाता है। साथ ही, मुझे लगता है कि यह तर्क दिया जा सकता है कि कोड को समझने में आसान बनाने के लिए वैसे भी ऐसा करना बेहतर नहीं है।

+0

धन्यवाद टस्टर, मुझे यह भी लगता है कि यह मुख्य कारण है और हां, यह वास्तव में sth करने के लिए उपयोगी नहीं है। मेरे नमूने की तरह (केवल ब्लॉक के क्रम को स्विच करें ...), बस समझ में नहीं आया क्यों पहले पल में ;-) –

+2

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

+0

@ एरिक लिपर्ट, विशेषज्ञ साक्ष्य के लिए धन्यवाद। – tster

संबंधित मुद्दे