नाम और वर्ग एक ही नाम के साथ?


95

मैं एक पुस्तकालय परियोजना का आयोजन कर रहा हूं और मेरे पास एक केंद्रीय प्रबंधक वर्ग है जिसका नाम Scenegraphऔर अन्य वर्गों का एक पूरा समूह है जो सीनग्राफ नामस्थान में रहते हैं।

क्या मैं वास्तव में पसंद करूंगा कि यह दृश्यपट के लिए है MyLib.Scenegraphऔर अन्य वर्गों के लिए है MyLib.Scenegraph.*, लेकिन ऐसा करने का एकमात्र तरीका ऐसा लगता है कि सभी अन्य वर्गों Scenegraphको सीनग्राफ.केएस की आंतरिक कक्षाओं में बनाना होगा और यह बहुत ही बेकार है ।

इसके बजाय, मैं इसे के रूप में व्यवस्थित किया है Mylib.Scenegraph.Scenegraphऔर MyLib.Scenegraph.*है, जो तरह काम करता है के, लेकिन मैं दृश्य स्टूडियो कि क्या मैं वर्ग या नाम स्थान का जिक्र कर रहा हूँ करने के लिए के रूप में कुछ शर्तों के तहत भ्रमित हो जाता है पाते हैं।

क्या इस पैकेज को व्यवस्थित करने का एक अच्छा तरीका है ताकि यह उपयोगकर्ताओं के लिए बिना किसी गड़बड़ के मेरे सभी कोड को एक साथ देखने के लिए सुविधाजनक हो?

जवाबों:


112

मैं आपको इसके नाम की तरह एक वर्ग का नाम देने की सलाह नहीं देता, यह देखें ।

फ्रेमवर्क डिज़ाइन दिशानिर्देश धारा 3.4 में कहते हैं, "नामस्थान के लिए समान नाम और उस नामस्थान में एक प्रकार का उपयोग न करें"। अर्थात्:

namespace MyContainers.List 
{ 
    public class List {  } 
}

यह बदतमीजी क्यों है? ओह, मुझे तरीके गिनने दो।

आप अपने आप को उन स्थितियों में ले जा सकते हैं जहाँ आपको लगता है कि आप एक बात का जिक्र कर रहे हैं लेकिन वास्तव में किसी और चीज का जिक्र कर रहे हैं। मान लें कि आप इस दुर्भाग्यपूर्ण स्थिति में समाप्त होते हैं: आप Blah.DLL लिख रहे हैं और Foo.DLL और Bar.DLL का आयात कर रहे हैं, जो दुर्भाग्य से, दोनों में एक प्रकार है जिसे फू कहा जाता है:

// Foo.DLL: 
namespace Foo { public class Foo { } }

// Bar.DLL: 
namespace Bar { public class Foo { } }

// Blah.DLL: 
namespace Blah  
{   
using Foo;   
using Bar;   
class C { Foo foo; } 
}

कंपाइलर एक त्रुटि देता है। "फू" फू फू और बार.फू के बीच अस्पष्ट है। ओह। मुझे लगता है कि मैं नाम को पूरी तरह से योग्य करके ठीक करूंगा:

   class C { Foo.Foo foo; } 

यह अब अस्पष्टता त्रुटि देता है " फू में फू। फू फू और बार.फू के बीच अस्पष्ट है ।" हम अभी भी नहीं जानते हैं कि पहला फू किसको संदर्भित करता है, और जब तक हम यह पता लगा सकते हैं, तब तक हम यह पता लगाने की कोशिश करने की जहमत नहीं उठाते हैं कि दूसरा किसका संदर्भ है।


6
इसका एक दिलचस्प बिंदु है। Im इस पर lcogitating। धन्यवाद। मुझे ईमानदार तर्क होना चाहिए जो "स्टाइल गाइड का कहना है" मुझे प्रभावित नहीं करता है। मैंने स्टाइल गाइडों में एक बहुत ही अनुचित बकवास देखा है। लेकिन आप ऊपर एक अच्छा व्यावहारिक तर्क देते हैं। वैसे भी सोचने लायक।
user430788

5
प्रतिक्रिया कहती है "क्या नहीं करना है"। जबकि कुछ स्टैक उपयोगकर्ता "क्या करना है" की तलाश करते हैं। क्या कोई Ant_222 जवाब देने की सिफारिश करेगा?
फंतासी

3
यदि आप वास्तव में फंस गए हैं, तब भी आप अपने नाम स्थान के बाहर एक प्रकार का उपनाम बना सकते हैं। बाहरी उपनाम केवल तब आवश्यक होते हैं जब आपके पास दो पूरी तरह से समान पूर्ण पहचानकर्ता (नाम स्थान + वर्ग नाम) हों।
जियोफ्रे

3
उपरोक्त सभी बाय-बाय और राय है। तथ्य यह है कि आप इसे नहीं करना चाहिए क्योंकि है सी # संकलक यह गलत होगा , काफी स्पष्ट रूप क्या हो रहा है कहा जा रहा है के बावजूद। उदाहरण के लिए, using Foo.Bar;बाद Bar bमें काफी स्पष्ट रूप Barसे नाम के अंदर एक वर्ग (या एनम) का उल्लेख है Foo.Bar। ऐसा न करने का वास्तविक कारण यह है कि शुद्ध रूप से C # संकलक इसे सही ढंग से समझने में विफल रहता है, जो आश्चर्यजनक रूप से आश्चर्यजनक और दुर्भाग्यपूर्ण है। कुछ भी ऊनी शैली की सलाह है।
टीजे क्राउडर

2
मुझे नहीं मिला। Foo.Foo अस्पष्ट क्यों है? आप सीधे संकलक से कहते हैं कि आप इस विशिष्ट मामले में नाम फू से वर्ग फू का उपयोग करना चाहते हैं। नहीं?
गार्जियनएक्स

14

नाम स्थान और वर्ग को एक ही नाम देना कंपाइलर को भ्रमित कर सकता है जैसा कि अन्य लोगों ने कहा है।

फिर इसका नाम कैसे दिया जाए?

यदि नाम स्थान में कई वर्ग हैं तो एक ऐसा नाम खोजें जो उन सभी वर्गों को परिभाषित करे।

यदि नामस्थान में केवल एक वर्ग है (और इसलिए इसे एक ही नाम देने का प्रलोभन) नामस्थान ClassName NS नाम है । यह कैसे Microsoft कम से कम अपने नामस्थान का नाम है।


4
क्या आपके पास Microsoft से ऐसे नामस्थान का एक उदाहरण है?
सूनफ्रेंड

मुझे इसे खोजना होगा और आपके पास वापस आना होगा।
गोतो

@sunefred मैंने इसे खोजा, लेकिन मुझे यह नहीं मिला। लेकिन मुझे यह याद है कि मैंने इसे प्रलेखन में देखा है। मुझे लगता है कि ऐसे कई मामले नहीं हैं, जब आप किसी एकल वर्ग का नाम स्थान में होना चाहते हैं।
GoTo

9

मेरा सुझाव है कि आप मेरे द्वारा microsoft.public.dotnet.languages.csharpउपयोग की गई सलाह का पालन करें MyLib.ScenegraphUtil.Scenegraphऔर MyLib.ScenegraphUtil.*


8

CA1724: Type Names Should Not Match Namespaces ...

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


4

बस मेरे 2 सेंट जोड़ना:

मेरे पास निम्न वर्ग था:

namespace Foo {
    public struct Bar {
    }
    public class Foo {
        //no method or member named "Bar"
    }
}

क्लाइंट को इस तरह लिखा गया था:

using Foo;

public class Blah {
    public void GetFoo( out Foo.Bar[] barArray ) {
    }
}

त्रुटि प्राप्त करने के लिए GetFoo आउट पैरामीटर का उपयोग करने के बजाय आउटपुट वापस नहीं कर रहा है, कंपाइलर डेटा प्रकार Foo.Bar [] को हल नहीं कर सका। यह त्रुटि लौटा रहा था: प्रकार या नामस्थान Foo.Bar नहीं मिला।

ऐसा प्रतीत होता है कि जब यह संकलन करने की कोशिश करता है तो फू को कक्षा के रूप में हल किया गया और कक्षा फू में एक एम्बेडेड क्लास बार नहीं मिला। यह Foo.Bar नामक एक नामस्थान भी नहीं खोज सका। यह नाम फू में एक क्लास बार की तलाश करने में विफल रहा। नाम स्थान में डॉट्स वाक्यात्मक नहीं हैं। पूरी स्ट्रिंग एक टोकन है, डॉट्स द्वारा सीमांकित शब्द नहीं।

यह व्यवहार वीएस 2015 रनिंग .net 4.6 द्वारा प्रदर्शित किया गया था


4

भले ही मैं अन्य उत्तरों से सहमत हूं कि आपको अपनी कक्षा का नाम नहीं देना चाहिए क्योंकि आपके नाम स्थान ऐसे हैं जिनमें आप ऐसी आवश्यकताओं का पालन नहीं कर सकते हैं।

उदाहरण के लिए मेरे मामले में मैं इस तरह का निर्णय लेने वाला व्यक्ति नहीं था इसलिए मुझे इसे काम करने का तरीका खोजने की आवश्यकता थी।

तो उन लोगों के लिए जो नाम स्थान का नाम नहीं बदल सकते हैं और न ही कक्षा का नाम एक ऐसा तरीका है जिसमें आप अपना कोड काम कर सकते हैं।

// Foo.DLL: 
namespace Foo { public class Foo { } }

// Bar.DLL: 
namespace Bar { public class Foo { } }

// Blah.DLL: 
namespace Blah
{
    using FooNSAlias = Foo;//alias
    using BarNSAlias = Bar;//alias
    class C { FooNSAlias.Foo foo; }//use alias to fully qualify class name
}

मूल रूप से मैंने नाम स्थान "उपनाम" बनाया और इससे मुझे कक्षा को पूरी तरह से योग्य बनाने की अनुमति मिली और विज़ुअल स्टूडियो "भ्रम" दूर हो गया।

नोट: यदि ऐसा करने के लिए आपके नियंत्रण में है तो आपको इस नामकरण संघर्ष से बचना चाहिए। आपको केवल उल्लेखित तकनीक का उपयोग करना चाहिए जब आप प्रश्न में कक्षाओं और नामस्थानों के नियंत्रण में न हों।


2
मैंने इसे वोट दिया क्योंकि यह अपूर्ण दुनिया का एक दिलचस्प समाधान था।
user430788

2

पुरानी पोस्ट, लेकिन यहां मैं एक और विचार के साथ जाता हूं जो किसी की मदद कर सकता है:

"... लेकिन ऐसा करने का एकमात्र तरीका ऐसा लगता है कि Scenegraph.cs फ़ाइल में सभी अन्य वर्गों को सीनग्राफ की आंतरिक कक्षाएं बनाना होगा और यह बहुत ही अवांछित है।"

यह वास्तव में परिदृश्यों के एक समूह के लिए बेहतर कार्यान्वयन है। लेकिन, मैं इस बात से सहमत हूं कि एक ही .cs फ़ाइल पर वह सब कोड होना कष्टप्रद है (कम से कम कहने के लिए)।

आप इसे आधार वर्ग को "आंशिक वर्ग" बनाकर हल कर सकते हैं और फिर, अपनी खुद की फाइलों पर आंतरिक कक्षाओं को बनाने पर जाएं (बस याद रखें कि उन्हें आधार वर्ग के पूरक की घोषणा करनी होगी और फिर विशिष्ट आंतरिक वर्ग के साथ जाना होगा। उस फ़ाइल के लिए)।

कुछ इस तरह...

Scenegraph.cs:

namespace MyLib
{
    public partial class Scenegraph
    {
        //Scenegraph specific implementations
    }
}

DependentClass.cs:

namespace MyLib
{
    public partial class Scenegraph
    {
        public class DependentClass
        {
            //DependentClass specific implementations
        }
    }
}

मुझे लगता है कि यह करीब है कि आप आंतरिक कक्षाओं के स्वच्छ कार्यान्वयन को प्राप्त कर सकते हैं, जबकि एक विशाल और गड़बड़ फ़ाइल के अंदर सब कुछ अव्यवस्थित नहीं करना है।


2

जैसा कि अन्य लोगों ने कहा है, किसी वर्ग का नामकरण करने से बचने के लिए यह एक अच्छा अभ्यास है।

यहाँ कुछ कर रहे हैं अतिरिक्त नामकरण सुझाव से svick द्वारा एक जवाब "वही वर्ग और नाम स्थान का नाम" सॉफ्टवेयर इंजीनियरिंग स्टैक एक्सचेंज पर एक संबंधित सवाल का:

आप सही कह रहे हैं कि आपको किसी भी प्रकार के नामस्थान का नाम नहीं देना चाहिए। मुझे लगता है कि कई दृष्टिकोण हैं जिनका आप उपयोग कर सकते हैं:

  • बहुवचन: Model.DataSource.DataSource

यह विशेष रूप से अच्छी तरह से काम करता है यदि नामस्थान का प्राथमिक उद्देश्य उन प्रकारों को समाहित करना है जो एक ही आधार प्रकार से वारिस होते हैं या समान इंटरफ़ेस को लागू करते हैं।

  • छोटा: मॉडल

यदि किसी नेमस्पेस में केवल कम संख्या में प्रकार होते हैं, तो शायद आपको उस नेमस्पेस की आवश्यकता नहीं है।

  • एंटरप्रीसी बनाएं: Model.ProjectSystem.Project

यह विशेष रूप से उन विशेषताओं के लिए काम कर सकता है जो आपके उत्पाद का महत्वपूर्ण हिस्सा हैं, इसलिए वे अपने स्वयं के नाम के लायक हैं।

(ध्यान दें कि ऊपर जवाब का उपयोग करता है Model.DataSource.DataSource, Model.QueryStorage.QueryStorage.और Model.Project.Projectके रूप में के बजाय उदाहरण MyLib.Scenegraph.Scenegraph।)

(मुझे अन्य उत्तरों में अन्य नामकरण के सुझाव भी मददगार लगे।)


1

यह तब होता है जब यह नामस्थान का मुख्य वर्ग होता है। तो यह एक प्रेरणा के लिए एक पुस्तकालय में नाम स्थान डाल दिया है, तो समस्या दूर हो जाती है यदि आप नाम सूची में 'Lib' जोड़ते हैं ...

namespace SocketLib
{
    class Socket
    {
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.