2010-07-01 15 views
6

निम्न शॉर्ट कोड स्निपेट पर विचार करें।क्या आप नामांकन घोषणाओं और सदस्यों के साथ सी # 'उपयोग' कीवर्ड से जुड़े इस एज केस को समझा सकते हैं?

namespace B 
{ 
    public class Foo 
    { 
     public string Text 
     { 
      get { return GetType().FullName; } 
     } 
    } 
} 

namespace A.B 
{ 
    public class Foo 
    { 
     public string Text 
     { 
      get { return GetType().FullName; } 
     } 
    } 
} 

साथ उदाहरण # 1 पहले परिचित हों।

using B; 

namespace A.C 
{ 
    public static class Program 
    { 
     public static void Main() 
     { 
      Console.WriteLine(new Foo().Text); 
     } 
    } 
} 

अब उदाहरण # 2 पर विचार करें।

namespace A.C 
{ 
    using B; // Notice the placement here. 

    public static class Program 
    { 
     public static void Main() 
     { 
      Console.WriteLine(new Foo().Text); 
     } 
    } 
} 

उदाहरण # 1 के बारे में बहुत कुछ अनोखा नहीं है। हालांकि, उदाहरण # 2 के साथ चीजें दिलचस्प हो जाती हैं। यह जरूरी है कि आप उदाहरणों में उपयोग किए गए सभी पहचानकर्ताओं पर ध्यान दें। एक मजेदार अभ्यास के रूप में यह अनुमान लगाने का प्रयास करें कि संकलक में इसे प्लग किए बिना क्या होता है। मैं यहां जवाब प्रकट नहीं करूंगा क्योंकि 1) अपने आप को आजमाने के लिए काफी आसान है और 2) मैं मस्ती को बर्बाद नहीं करना चाहता हूं।

कार्यक्रम होगा:

  • संकलन नहीं
  • प्रदर्शन B.Foo
  • प्रदर्शन ABFoo

सवाल ... कहाँ सी # विनिर्देश में इस व्यवहार को वर्णित है ?

मैंने सी # 4.0 विनिर्देशन और विशेष रूप से बुलेट # 2 में सेक्शन 3.7 पर एक नज़र डाली, लेकिन मुझे नहीं लगता कि यह व्यवहार बताता है। अगर कुछ भी मुझे लगभग सोचता है कि संकलक विनिर्देश के विपरीत विरोधाभासी व्यवहार कर रहा है।

+0

आपको इस प्रश्न को इस ब्लॉग के लेखक को पोस्ट करना चाहिए: http://blogs.msdn.com/b/ericlippert/ वह आपके लिए बिल्कुल जवाब देगा। – David

+0

मैं अपने ब्लॉग से परिचित हूं। वह अक्सर एसओ पर पोस्ट करता है ताकि वह यहां एक स्टैब ले सके। –

+0

हाँ, मैं एरिक के का इंतजार कर रहा हूँ अपने आप का जवाब :) –

उत्तर

7

पहला उदाहरण प्रिंट "B.Foo", दूसरे उदाहरण प्रिंट "ABFoo" करने के लिए हल। ऐसा इसलिए है क्योंकि दूसरे उदाहरण में using B; निर्देश A.C नामस्थान के अंदर संलग्न है।

B के बजाय A.B का उपयोग क्यों करता है?

क्योंकि नामस्थान लुकअप टाइप नाम योग्यता लुकअप के समान नियमों का पालन करते हैं। सी # spec के Section 3.8

असल में, जब using निर्देशक संकलक द्वारा संसाधित किया जाता है, तो B प्रतीक A.C नामस्थान में देखा जाता है। इसे नहीं मिला, यह A नामस्थान में देखा गया है।चूंकि यह A के उप-नामस्थान के रूप में पाया जाता है, यह उस नामस्थान का चयन करता है और B नामस्थान खोजने के लिए वैश्विक नामस्थान पर नहीं जाता है।

संपादित करें: @ P.Brian.Mackey पता चलता है
रूप में, आप using global::B; साथ B नाम स्थान के लिए मिल सकता है।

+1

हाँ, मुझे लगता है कि आप सही हैं। प्रासंगिक टुकड़ा 3.8 बुलेट # 1 सब-बुलेट # 2 में है। यह निश्चित रूप से, लेकिन स्पष्ट रूप से नहीं, इस बैकट्रैकिंग व्यवहार का वर्णन करता है। अच्छा पकड़ा। –

+0

@ ब्रेन: यह तीन गोलियों के साथ एक है। – Randolpho

5

मैंने सी # विनिर्देशों को नहीं पढ़ा, लेकिन मैं आपको बता सकता हूं कि कटौती से क्या हो रहा है। जब आप एसी नेमस्पेस के अंदर बी का उपयोग करते हैं तो आप अब वैश्विक दायरे में नहीं हैं, आप आस-पास के नामस्थान के दायरे में हैं।

using global::B; 

जोड़कर आप आगे इस घटित देख सकते हैं लेकिन,: सबसे पहले एप्लिकेशन एसी में हल करने के लिए है, तो ए में

सबसे आसान ठीक बस के कथन का उपयोग अंदर बदलने के लिए है की कोशिश करेंगे

namespace A.C.B 
{ 
    public class Foo 
    { 
     public string Text 
     { 
      get { return GetType().FullName; } 
     } 
    } 
} 

ध्यान दें कि आप अब एसीबी

+0

+1, लेकिन मुझे लगता है कि आप जिसमें संकल्प पीछे की ओर होता है आदेश मिल गया है। इसे पहले 'एसी' में हल करने का प्रयास करना चाहिए, फिर 'ए'। – Randolpho

+1

सुधार के लिए धन्यवाद। यह बनाया गया है। –

+0

रास्ते से 'वैश्विक :: बी' चाल पर अच्छी युक्ति। –

0

मेरा मानना ​​है कि कल्पना की उचित भागों हैं:

3.4.1 नामस्थान सदस्यों

नेमस्पेस और प्रकार कोई संलग्नित नाम स्थान है कि ग्लोबल नेम स्पेस के सदस्य हैं। यह वैश्विक घोषणा स्थान पर घोषित नामों से सीधे मेल खाता है।

नेमस्पेस और प्रकार घोषित एक namespace के भीतर उस नाम स्थान के सदस्य हैं। नामस्थान की घोषणा स्थान में घोषित नामों के लिए यह सीधे से मेल खाता है।

नेमस्पेस के पास प्रतिबंधों का कोई उपयोग नहीं है। निजी, संरक्षित, या आंतरिक नामस्थान घोषित करना संभव नहीं है, और नामस्थान नाम हमेशा सार्वजनिक रूप से पहुंच योग्य होते हैं।

साथ ही धारा 9.4.2 जो चर्चा करता है कि निर्देशों का उपयोग कैसे पहचानकर्ताओं के स्कॉप्ड पुनर्वसन को प्रभावित करता है।

4

अन्य उत्तरों सही हैं, लेकिन एक अतिरिक्त नोट। यह याद रखना महत्वपूर्ण है कि

namespace A.C 
{ 
    using B; 

वास्तव में सिर्फ लेखन

namespace A 
{ 
    namespace C 
    { 
     using B; 

की एक छोटी रास्ता कौन सा हो सकता है यह थोड़ा और अधिक स्पष्ट यहाँ क्या हो रहा है है में मदद करता है। जब बी को हल हम बी के लिए एक जाँच इससे पहले कि हम ए के कंटेनर जाँच

आप तरीके में रुचि है कि नाम स्थान लुकअप बुरी तरह गलत हो सकता है कर रहे हैं, कि के बारे में लेख की मेरी श्रृंखला देखें:

http://blogs.msdn.com/b/ericlippert/archive/tags/namespaces/

+0

अच्छा ब्लॉग, धन्यवाद। –

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