c# - 'उपयोग' निर्देशों को नामस्थान के अंदर या बाहर होना चाहिए?




.net namespaces (6)

इस धागे में पहले से ही कुछ शानदार जवाब हैं, लेकिन मुझे लगता है कि मैं इस अतिरिक्त उत्तर के साथ थोड़ा और विवरण ला सकता हूं।

सबसे पहले, याद रखें कि अवधि के साथ एक नामस्थान घोषणा, जैसे:

namespace MyCorp.TheProduct.SomeModule.Utilities
{
    ...
}

पूरी तरह से बराबर है:

namespace MyCorp
{
    namespace TheProduct
    {
        namespace SomeModule
        {
            namespace Utilities
            {
                ...
            }
        }
    }
}

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

किस प्रकार को हल करने के लिए नियम को निहित किया गया है, इस तरह संक्षेप में कहा जा सकता है: पहले किसी भी मैच के लिए आंतरिक-सबसे अधिक "दायरा" खोजें, यदि कुछ भी नहीं मिला है तो अगले स्तर पर एक स्तर बाहर निकलें और वहां खोजें, और इसी तरह , एक मैच मिलने तक। यदि किसी स्तर पर एक से अधिक मैच मिलते हैं, तो यदि किसी एक प्रकार की मौजूदा असेंबली से हैं, तो उसे चुनें और एक कंपाइलर चेतावनी जारी करें। अन्यथा, छोड़ दें (संकलन-समय त्रुटि)।

अब, दो प्रमुख सम्मेलनों के साथ एक ठोस उदाहरण में इसका क्या अर्थ है इसके बारे में स्पष्ट रहें।

(1) बाहर के उपयोग के साथ:

using System;
using System.Collections.Generic;
using System.Linq;
//using MyCorp.TheProduct;  <-- uncommenting this would change nothing
using MyCorp.TheProduct.OtherModule;
using MyCorp.TheProduct.OtherModule.Integration;
using ThirdParty;

namespace MyCorp.TheProduct.SomeModule.Utilities
{
    class C
    {
        Ambiguous a;
    }
}

उपर्युक्त मामले में, यह पता लगाने के लिए कि किस प्रकार Ambiguous है, खोज इस क्रम में जाती है:

  1. C अंदर नेस्टेड प्रकार (विरासत नेस्टेड प्रकार सहित)
  2. वर्तमान नेमस्पेस MyCorp.TheProduct.SomeModule.Utilities में प्रकार
  3. नेमस्पेस MyCorp.TheProduct.SomeModule में प्रकार
  4. MyCorp.TheProduct में प्रकार
  5. MyCorp में प्रकार
  6. शून्य नामस्थान में प्रकार (वैश्विक नामस्थान)
  7. System में System , SystemMyCorp.TheProduct.OtherModuleMyCorp.TheProduct.OtherModule.Integration , SystemMyCorp.TheProduct.OtherModule , MyCorp.TheProduct.OtherModule.Integration , MyCorp.TheProduct.OtherModule.Integration , और ThirdParty

दूसरा सम्मेलन:

(2) अंदर उपयोग के साथ:

namespace MyCorp.TheProduct.SomeModule.Utilities
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using MyCorp.TheProduct;                           // MyCorp can be left out; this using is NOT redundant
    using MyCorp.TheProduct.OtherModule;               // MyCorp.TheProduct can be left out
    using MyCorp.TheProduct.OtherModule.Integration;   // MyCorp.TheProduct can be left out
    using ThirdParty;

    class C
    {
        Ambiguous a;
    }
}

अब, इस आदेश में Ambiguous प्रकार के लिए खोज करें:

  1. C अंदर नेस्टेड प्रकार (विरासत नेस्टेड प्रकार सहित)
  2. वर्तमान नेमस्पेस MyCorp.TheProduct.SomeModule.Utilities में प्रकार
  3. System में System , SystemMyCorp.TheProductMyCorp.TheProduct.OtherModule , SystemMyCorp.TheProduct , MyCorp.TheProduct.OtherModule MyCorp.TheProduct , MyCorp.TheProduct.OtherModule , MyCorp.TheProduct.OtherModule.Integration , और ThirdParty
  4. नेमस्पेस MyCorp.TheProduct.SomeModule में प्रकार
  5. MyCorp में प्रकार
  6. शून्य नामस्थान में प्रकार (वैश्विक नामस्थान)

(ध्यान दें कि MyCorp.TheProduct "3." का हिस्सा था और इसलिए "4." और "5." के बीच की आवश्यकता नहीं थी।)

समापन टिप्पणी

इससे कोई फर्क नहीं पड़ता कि आप नेमस्पेस घोषणा के अंदर या बाहर उपयोग करते हैं, फिर भी संभावना है कि कोई व्यक्ति बाद में नामों में से एक को समान नाम के साथ एक नया प्रकार जोड़ता है जिसमें उच्च प्राथमिकता है।

साथ ही, यदि एक नेस्टेड नेमस्पेस का एक ही नाम एक ही प्रकार है, तो इससे समस्याएं पैदा हो सकती हैं।

उपयोग को एक स्थान से दूसरे स्थान पर ले जाना हमेशा खतरनाक होता है क्योंकि खोज पदानुक्रम बदलता है, और दूसरा प्रकार पाया जा सकता है। इसलिए, एक सम्मेलन चुनें और इसके साथ चिपके रहें, ताकि आपको कभी भी उपयोग नहीं करना पड़ेगा।

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

बाहर का उपयोग करने का एक (छोटा) लाभ यह है कि आप वैश्विक विशेषता के लिए उपयोग निर्देशों का उपयोग कर सकते हैं, उदाहरण के लिए [assembly: ComVisible(false)] [assembly: System.Runtime.InteropServices.ComVisible(false)] बजाय।

https://code.i-harness.com

मैं कुछ सी # कोड पर StyleCop चला रहा हूं, और यह रिपोर्टिंग करता रहता है कि मेरे using निर्देश नामस्थान के अंदर होना चाहिए।

नामस्थान के बाहर के बजाय using निर्देशों को डालने का कोई तकनीकी कारण है?


इसे नामस्थानों के अंदर रखकर फ़ाइल के लिए उस नेमस्पेस में स्थानीय घोषणाएं होती हैं (यदि आपके पास फ़ाइल में एकाधिक नामस्थान हैं) लेकिन यदि आपके पास प्रति फ़ाइल केवल एक नेमस्पेस है तो इससे कोई फर्क नहीं पड़ता कि वे बाहर जाते हैं या नहीं नामस्थान के अंदर।

using ThisNamespace.IsImported.InAllNamespaces.Here;

namespace Namespace1
{ 
   using ThisNamespace.IsImported.InNamespace1.AndNamespace2;

   namespace Namespace2
   { 
      using ThisNamespace.IsImported.InJustNamespace2;
   }       
}

namespace Namespace3
{ 
   using ThisNamespace.IsImported.InJustNamespace3;
}

जैसा कि जेप्पे स्टिग नील्सन said , इस धागे में पहले से ही बहुत अच्छे जवाब हैं, लेकिन मैंने सोचा कि यह स्पष्ट सूक्ष्मता भी उल्लेखनीय है।

नेमस्पेस के अंदर निर्दिष्ट निर्देशों using छोटे कोड के लिए बना सकते हैं क्योंकि उन्हें बाहरी रूप से निर्दिष्ट होने पर पूरी तरह से योग्यता प्राप्त करने की आवश्यकता नहीं होती है।

निम्नलिखित उदाहरण काम करता है क्योंकि Foo और Bar प्रकार एक ही वैश्विक नामस्थान, Outer दोनों हैं।

कोड फ़ाइल Foo.cs मानें :

namespace Outer.Inner
{
    class Foo { }
}

और बार. cs :

namespace Outer
{
    using Outer.Inner;

    class Bar
    {
        public Foo foo;
    }
}

यह छोटे नाम के लिए using निर्देश में बाहरी नेमस्पेस को छोड़ सकता है:

namespace Outer
{
    using Inner;

    class Bar
    {
        public Foo foo;
    }
}

यह एक बेहतर अभ्यास है यदि आपके स्रोत समाधान में उपयोग किए जाने वाले " संदर्भ " अर्थात डिफ़ॉल्ट नामों के बाहर होना चाहिए और जो "नया जोड़ा संदर्भ" हैं , एक अच्छा अभ्यास है, आपको इसे नामस्थान के अंदर रखना चाहिए। यह अंतर करना है कि संदर्भ क्या जोड़े जा रहे हैं।


स्टाइलकॉप दस्तावेज़ीकरण के अनुसार:

एसए 1200: डायरेक्ट डायरेक्टिव्सस्टस्टेप्लेसविथिन नेमस्पेस

निर्देश का उपयोग कर एसी # को नेमस्पेस तत्व के बाहर रखा गया है।

नियम विवरण इस नियम का उल्लंघन तब होता है जब कोई उपयोग निर्देश या उपयोग-उपनाम निर्देश किसी नामस्थान तत्व के बाहर रखा जाता है, जब तक कि फ़ाइल में कोई नामस्थान तत्व न हो।

उदाहरण के लिए, निम्नलिखित कोड के परिणामस्वरूप इस नियम के दो उल्लंघन होंगे।

using System;
using Guid = System.Guid;

namespace Microsoft.Sample
{
    public class Program
    {
    }
}

हालांकि, निम्नलिखित कोड के परिणामस्वरूप इस नियम का कोई उल्लंघन नहीं होगा:

namespace Microsoft.Sample
{
    using System;
    using Guid = System.Guid;

    public class Program
    {
    }
}

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

namespace Microsoft.Sample
{
    using Guid = System.Guid;
    public class Guid
    {
        public Guid(string s)
        {
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Guid g = new Guid("hello");
        }
    }
}

कोड निम्न संकलक त्रुटि पर विफल रहता है, जिसमें Guid g = new Guid("hello"); वाली रेखा पर पाया गया है Guid g = new Guid("hello");

सीएस0576: नेमस्पेस 'माइक्रोसॉफ्ट। नमूना' में उपनाम 'ग्विड' के साथ विरोधाभासी परिभाषा है

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

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

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

नेमस्पेस तत्व के भीतर-उपनाम निर्देशों का उपयोग करना इसे बग के स्रोत के रूप में समाप्त करता है।

  1. एकाधिक नामस्थान

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

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

उल्लंघनों को कैसे ठीक करें इस नियम के उल्लंघन को ठीक करने के लिए, नामस्थान तत्व के भीतर निर्देशों और उपयोग-उपनाम निर्देशों का उपयोग करके सभी को स्थानांतरित करें।








code-organization