.Net में नेस्टेड क्लासेस का उपयोग क्यों / कब करना चाहिए? या आपको नहीं करना चाहिए?


93

में कैथलीन Dollard के 2008 ब्लॉग पोस्ट , वह .net में नेस्टेड वर्गों का उपयोग करने के लिए एक दिलचस्प कारण प्रस्तुत करता है। हालाँकि, उसने यह भी उल्लेख किया कि FxCop को नेस्टेड क्लास पसंद नहीं है। मैं मान रहा हूं कि एफएक्सपॉप नियम लिखने वाले लोग मूर्ख नहीं हैं, इसलिए उस स्थिति के पीछे तर्क होना चाहिए, लेकिन मैं इसे ढूंढ नहीं पाया।


ब्लॉग पोस्ट में
वेकबैक

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

जवाबों:


96

नेस्टेड क्लास का उपयोग करें जब आप जिस क्लास में नेस्ट कर रहे हैं वह केवल एनक्लोजिंग क्लास के लिए उपयोगी है। उदाहरण के लिए, नेस्टेड कक्षाएं आपको कुछ लिखने की अनुमति देती हैं जैसे (सरलीकृत):

public class SortedMap {
    private class TreeNode {
        TreeNode left;
        TreeNode right;
    }
}

आप अपनी कक्षा की एक पूरी परिभाषा एक जगह पर बना सकते हैं, आपको यह बताने के लिए कि आपकी कक्षा कैसे काम करती है, और बाहरी दुनिया को आपके कार्यान्वयन के बारे में कुछ भी देखने की आवश्यकता नहीं है, को परिभाषित करने के लिए किसी भी PIMPL हुप्स के माध्यम से कूदना नहीं है।

यदि ट्रीनोड वर्ग बाहरी था, तो आपको या तो सभी क्षेत्रों को बनाना होगा या इसका उपयोग करने के लिए तरीकों का publicएक गुच्छा बनाना get/setहोगा। बाहरी दुनिया के पास एक और वर्ग होता है जो उनकी अंतर्मुखता को प्रदूषित करता है।


44
इसे जोड़ने के लिए: आप अपने कोड को बेहतर तरीके से प्रबंधित करने के लिए अलग-अलग फ़ाइलों में आंशिक कक्षाओं का उपयोग कर सकते हैं। एक अलग फाइल में आंतरिक वर्ग रखें (SortedMap.TreeNode.cs इस मामले में)। यह आपके कोड को साफ रखना चाहिए, जबकि आपके कोड को अलग रखना भी :)
एरिक वैन ब्रैकेल सेप

1
ऐसे मामले होंगे जहां आपको नेस्टेड क्लास को सार्वजनिक या आंतरिक बनाने की आवश्यकता होगी यदि इसका उपयोग सार्वजनिक एपीआई या कंटेनर वर्ग की सार्वजनिक संपत्ति के बदले में किया जा रहा है। मुझे यकीन नहीं है कि यह एक अच्छा अभ्यास है। इस तरह के मामलों में कंटेनर क्लास के बाहर नेस्टेड क्लास को बाहर निकालने के लिए अधिक समझ हो सकती है। System.Windows.Forms.ListViewItem.ListViewSubItem में .Net फ्रेमवर्क एक ऐसा उदाहरण है।
RBT

16

सूर्य के जावा ट्यूटोरियल से:

नेस्टेड क्लास का उपयोग क्यों करें? नेस्टेड वर्गों का उपयोग करने के लिए कई सम्मोहक कारण हैं, उनमें से:

  • यह तार्किक रूप से समूहन वर्गों का एक तरीका है जो केवल एक ही स्थान पर उपयोग किया जाता है।
  • यह एन्कैप्सुलेशन को बढ़ाता है।
  • नेस्टेड कक्षाएं अधिक पठनीय और बनाए रखने योग्य कोड को जन्म दे सकती हैं।

कक्षाओं का तार्किक समूहन- यदि कोई वर्ग केवल एक अन्य वर्ग के लिए उपयोगी है, तो उसे उस कक्षा में एम्बेड करना और दोनों को एक साथ रखना तर्कसंगत है। ऐसे "हेल्पर वर्गों" का घोंसला बनाना उनके पैकेज को अधिक सुव्यवस्थित बनाता है।

एन्कैप्सुलेशन में वृद्धि - दो शीर्ष-स्तरीय कक्षाओं पर विचार करें, ए और बी, जहां बी को ए के सदस्यों तक पहुंच की आवश्यकता है जो अन्यथा निजी घोषित किए जाएंगे। कक्षा बी को कक्षा ए के भीतर छिपाकर, ए के सदस्यों को निजी घोषित किया जा सकता है और बी उन्हें एक्सेस कर सकते हैं। इसके अलावा, बी खुद को बाहरी दुनिया से छिपाया जा सकता है। <- यह नेस्टेड कक्षाओं के C # के कार्यान्वयन पर लागू नहीं होता है, यह केवल जावा पर लागू होता है।

अधिक पठनीय, रख-रखाव कोड - शीर्ष-स्तरीय कक्षाओं के भीतर छोटी कक्षाओं को घोंसले में रखना कोड को उस स्थान के करीब रखता है जहाँ इसका उपयोग किया जाता है।


1
यह वास्तव में लागू नहीं होता है, जैसा कि आप जावा में एन्ग्लोसिंग वर्ग से C # में इंस्टेंस चर का उपयोग नहीं कर सकते हैं। केवल स्थैतिक सदस्य ही सुलभ हैं।
बेन बैरन

5
हालाँकि, यदि आप एन्क्लेडिंग वर्ग का एक उदाहरण नेस्टेड क्लास में पास करते हैं, तो नेस्टेड क्लास के पास उस उदाहरण चर के माध्यम से सभी सदस्यों तक पूरी पहुँच होती है ... तो वास्तव में, यह जावा की तरह है जो उदाहरण चर को अंतर्निहित करता है, जबकि C # में आपको इसे स्पष्ट करें।
एलेक्स

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

2
@ TomášZato मेरा वर्णन बहुत उपयुक्त है, वास्तव में। जावा में नेस्टेड कक्षाओं में प्रभावी रूप से एक अंतर्निहित अभिभावक उदाहरण चर है, जबकि C # में, आपको स्पष्ट रूप से आंतरिक वर्ग का उदाहरण देना होगा। इसका एक परिणाम, जैसा कि आप कहते हैं, यह है कि जावा के आंतरिक वर्गों के पास एक मूल उदाहरण होना चाहिए, जबकि C # नहीं है। किसी भी मामले में मेरा मुख्य बिंदु यह था कि C # की आंतरिक कक्षाएं अपने माता-पिता के निजी क्षेत्रों और संपत्तियों तक भी पहुंच बना सकती हैं, लेकिन यह करने में सक्षम होने के लिए माता-पिता के उदाहरण को स्पष्ट रूप से पारित करना होगा।
एलेक्स

9

पूरी तरह से आलसी और धागा-सुरक्षित सिंगलटन पैटर्न

public sealed class Singleton
{
    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return Nested.instance;
        }
    }

    class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

स्रोत: http://www.yoda.arachsys.com/csharp/singleton.html


5

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

यदि क्लास का उपयोग कॉलर द्वारा किया जाता है (बाहरी रूप से), तो मैं आमतौर पर इसे एक अलग स्टैंडअलोन क्लास बनाना पसंद करता हूं।


5

ऊपर सूचीबद्ध अन्य कारणों के अलावा, एक और कारण है कि मैं न केवल नेस्टेड कक्षाओं का उपयोग करने के बारे में सोच सकता हूं, लेकिन वास्तव में सार्वजनिक नेस्टेड कक्षाएं। जो एक ही सामान्य प्रकार के मापदंडों को साझा करने वाले कई सामान्य वर्गों के साथ काम करते हैं, उनके लिए जेनेरिक नेमस्पेस घोषित करने की क्षमता बेहद उपयोगी होगी। दुर्भाग्य से, .Net (या कम से कम C #) जेनेरिक नेमस्पेस के विचार का समर्थन नहीं करता है। तो उसी लक्ष्य को पूरा करने के लिए, हम उसी लक्ष्य को पूरा करने के लिए जेनेरिक कक्षाओं का उपयोग कर सकते हैं। तार्किक इकाई से संबंधित निम्नलिखित उदाहरण कक्षाएं लें:

public  class       BaseDataObject
                    <
                        tDataObject, 
                        tDataObjectList, 
                        tBusiness, 
                        tDataAccess
                    >
        where       tDataObject     : BaseDataObject<tDataObject, tDataObjectList, tBusiness, tDataAccess>
        where       tDataObjectList : BaseDataObjectList<tDataObject, tDataObjectList, tBusiness, tDataAccess>, new()
        where       tBusiness       : IBaseBusiness<tDataObject, tDataObjectList, tBusiness, tDataAccess>
        where       tDataAccess     : IBaseDataAccess<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
}

public  class       BaseDataObjectList
                    <
                        tDataObject, 
                        tDataObjectList, 
                        tBusiness, 
                        tDataAccess
                    >
:   
                    CollectionBase<tDataObject>
        where       tDataObject     : BaseDataObject<tDataObject, tDataObjectList, tBusiness, tDataAccess>
        where       tDataObjectList : BaseDataObjectList<tDataObject, tDataObjectList, tBusiness, tDataAccess>, new()
        where       tBusiness       : IBaseBusiness<tDataObject, tDataObjectList, tBusiness, tDataAccess>
        where       tDataAccess     : IBaseDataAccess<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
}

public  interface   IBaseBusiness
                    <
                        tDataObject, 
                        tDataObjectList, 
                        tBusiness, 
                        tDataAccess
                    >
        where       tDataObject     : BaseDataObject<tDataObject, tDataObjectList, tBusiness, tDataAccess>
        where       tDataObjectList : BaseDataObjectList<tDataObject, tDataObjectList, tBusiness, tDataAccess>, new()
        where       tBusiness       : IBaseBusiness<tDataObject, tDataObjectList, tBusiness, tDataAccess>
        where       tDataAccess     : IBaseDataAccess<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
}

public  interface   IBaseDataAccess
                    <
                        tDataObject, 
                        tDataObjectList, 
                        tBusiness, 
                        tDataAccess
                    >
        where       tDataObject     : BaseDataObject<tDataObject, tDataObjectList, tBusiness, tDataAccess>
        where       tDataObjectList : BaseDataObjectList<tDataObject, tDataObjectList, tBusiness, tDataAccess>, new()
        where       tBusiness       : IBaseBusiness<tDataObject, tDataObjectList, tBusiness, tDataAccess>
        where       tDataAccess     : IBaseDataAccess<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{
}

हम एक सामान्य नाम स्थान (नेस्टेड कक्षाओं के माध्यम से कार्यान्वित) का उपयोग करके इन वर्गों के हस्ताक्षर को सरल बना सकते हैं:

public
partial class   Entity
                <
                    tDataObject, 
                    tDataObjectList, 
                    tBusiness, 
                    tDataAccess
                >
        where   tDataObject     : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.BaseDataObject
        where   tDataObjectList : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.BaseDataObjectList, new()
        where   tBusiness       : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.IBaseBusiness
        where   tDataAccess     : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.IBaseDataAccess
{

    public  class       BaseDataObject {}

    public  class       BaseDataObjectList : CollectionBase<tDataObject> {}

    public  interface   IBaseBusiness {}

    public  interface   IBaseDataAccess {}

}

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

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

Entity.cs

public
partial class   Entity
                <
                    tDataObject, 
                    tDataObjectList, 
                    tBusiness, 
                    tDataAccess
                >
        where   tDataObject     : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.BaseDataObject
        where   tDataObjectList : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.BaseDataObjectList, new()
        where   tBusiness       : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.IBaseBusiness
        where   tDataAccess     : Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>.IBaseDataAccess
{
}

Entity.BaseDataObject.cs

partial class   Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{

    public  class   BaseDataObject
    {

        public  DataTimeOffset  CreatedDateTime     { get; set; }
        public  Guid            CreatedById         { get; set; }
        public  Guid            Id                  { get; set; }
        public  DataTimeOffset  LastUpdateDateTime  { get; set; }
        public  Guid            LastUpdatedById     { get; set; }

        public
        static
        implicit    operator    tDataObjectList(DataObject dataObject)
        {
            var returnList  = new tDataObjectList();
            returnList.Add((tDataObject) this);
            return returnList;
        }

    }

}

Entity.BaseDataObjectList.cs

partial class   Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{

    public  class   BaseDataObjectList : CollectionBase<tDataObject>
    {

        public  tDataObjectList ShallowClone() 
        {
            var returnList  = new tDataObjectList();
            returnList.AddRange(this);
            return returnList;
        }

    }

}

Entity.IBaseBusiness.cs

partial class   Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{

    public  interface   IBaseBusiness
    {
        tDataObjectList Load();
        void            Delete();
        void            Save(tDataObjectList data);
    }

}

Entity.IBaseDataAccess.cs

partial class   Entity<tDataObject, tDataObjectList, tBusiness, tDataAccess>
{

    public  interface   IBaseDataAccess
    {
        tDataObjectList Load();
        void            Delete();
        void            Save(tDataObjectList data);
    }

}

विज़ुअल स्टूडियो सॉल्यूशन एक्सप्लोरर की फाइलों को फिर इस तरह व्यवस्थित किया जाएगा:

Entity.cs
+   Entity.BaseDataObject.cs
+   Entity.BaseDataObjectList.cs
+   Entity.IBaseBusiness.cs
+   Entity.IBaseDataAccess.cs

और आप निम्नलिखित की तरह सामान्य नामस्थान लागू करेंगे:

User.cs

public
partial class   User
:
                Entity
                <
                    User.DataObject, 
                    User.DataObjectList, 
                    User.IBusiness, 
                    User.IDataAccess
                >
{
}

User.DataObject.cs

partial class   User
{

    public  class   DataObject : BaseDataObject 
    {
        public  string  UserName            { get; set; }
        public  byte[]  PasswordHash        { get; set; }
        public  bool    AccountIsEnabled    { get; set; }
    }

}

User.DataObjectList.cs

partial class   User
{

    public  class   DataObjectList : BaseDataObjectList {}

}

User.IBusiness.cs

partial class   User
{

    public  interface   IBusiness : IBaseBusiness {}

}

User.IDataAccess.cs

partial class   User
{

    public  interface   IDataAccess : IBaseDataAccess {}

}

और फाइलों को हल एक्सप्लोरर में व्यवस्थित किया जाएगा:

User.cs
+   User.DataObject.cs
+   User.DataObjectList.cs
+   User.IBusiness.cs
+   User.IDataAccess.cs

उपरोक्त एक सामान्य नेमस्पेस के रूप में बाहरी वर्ग का उपयोग करने का एक सरल उदाहरण है। मैंने "जेनेरिक नेमस्पेस" बनाया है जिसमें पूर्व में 9 या अधिक प्रकार के पैरामीटर हैं। उन प्रकार के मापदंडों को पूरे नौ प्रकारों में समकालिक रखने के लिए, जो सभी प्रकार के मापदंडों को जानने के लिए आवश्यक थे, विशेष रूप से एक नया पैरामीटर जोड़ते समय थकाऊ था। जेनेरिक नामस्थान का उपयोग उस कोड को अधिक प्रबंधनीय और पठनीय बनाता है।


3

अगर मैं कैथलीन के लेख को सही समझता हूं, तो वह एनटाइटिस क्लास का उपयोग करने का प्रस्ताव करती है ताकि एंटाइटेलक्लेक्शन <SomeEntity> के बजाय SomeEntity.Collection लिखने में सक्षम हो सके। मेरी राय में यह कुछ टाइपिंग को बचाने के लिए विवादास्पद तरीका है। मुझे पूरा यकीन है कि वास्तविक विश्व अनुप्रयोग संग्रहों में कार्यान्वयन में कुछ अंतर होगा, इसलिए आपको वैसे भी अलग वर्ग बनाने की आवश्यकता होगी। मुझे लगता है कि अन्य वर्ग गुंजाइश को सीमित करने के लिए वर्ग नाम का उपयोग करना एक अच्छा विचार नहीं है। यह वर्गों के बीच निर्भरता को मजबूत करता है। नाम स्थान का उपयोग करना वर्गों के दायरे को नियंत्रित करने का एक मानक तरीका है। हालाँकि मुझे लगता है कि @hazzen टिप्पणी में नेस्टेड वर्गों का उपयोग तब तक स्वीकार्य है जब तक कि आपके पास नेस्टेड कक्षाओं का टन न हो जो खराब डिज़ाइन का संकेत है।


1

कार्यान्वयन विवरण को छिपाने के लिए मैं अक्सर नेस्टेड कक्षाओं का उपयोग करता हूं। एरिक लिपर्ट के जवाब से एक उदाहरण यहाँ है:

abstract public class BankAccount
{
    private BankAccount() { }
    // Now no one else can extend BankAccount because a derived class
    // must be able to call a constructor, but all the constructors are
    // private!
    private sealed class ChequingAccount : BankAccount { ... }
    public static BankAccount MakeChequingAccount() { return new ChequingAccount(); }
    private sealed class SavingsAccount : BankAccount { ... }
}

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

Equality<Person>.CreateComparer(p => p.Id);

के बजाय

new EqualityComparer<Person, int>(p => p.Id);

इसके अलावा मेरे पास एक सामान्य सूची हो सकती है Equality<Person>लेकिन नहींEqualityComparer<Person, int>

var l = new List<Equality<Person>> 
        { 
         Equality<Person>.CreateComparer(p => p.Id),
         Equality<Person>.CreateComparer(p => p.Name) 
        }

जहाँ तक

var l = new List<EqualityComparer<Person, ??>>> 
        { 
         new EqualityComparer<Person, int>>(p => p.Id),
         new EqualityComparer<Person, string>>(p => p.Name) 
        }

संभव नहीं है। माता-पिता वर्ग से विरासत में प्राप्त नेस्टेड वर्ग का लाभ है।

एक और मामला (उसी प्रकृति का - कार्यान्वयन को छिपाते हुए) है जब आप एक वर्ग के सदस्यों (क्षेत्र, गुण आदि) को केवल एक वर्ग के लिए सुलभ बनाना चाहते हैं:

public class Outer 
{
   class Inner //private class
   {
       public int Field; //public field
   }

   static inner = new Inner { Field = -1 }; // Field is accessible here, but in no other class
}

1

नेस्टेड वर्गों के लिए अभी तक उल्लेख नहीं किया गया एक और उपयोग सामान्य प्रकारों का अलगाव है। उदाहरण के लिए, मान लीजिए कि कोई व्यक्ति स्थिर वर्गों के कुछ सामान्य परिवारों को रखना चाहता है, जो उन मापदंडों में से कुछ के लिए मानों के साथ-साथ विभिन्न मापदंडों के तरीकों को ले सकते हैं, और कम मापदंडों के साथ प्रतिनिधि उत्पन्न कर सकते हैं। उदाहरण के लिए, कोई एक स्थिर विधि की इच्छा रखता है जो एक ले सकता है Action<string, int, double>और एक उपज ले सकता है String<string, int>जो आपूर्ति की गई कार्रवाई को 3.5 के रूप में पारित करेगा double; एक भी एक स्थिर तरीका है जिसके एक एक लग सकते हैं चाहते हो सकता है Action<string, int, double>और एक उपज Action<string>, गुजर 7के रूप में intऔर 5.3के रूप में double। जेनेरिक नेस्टेड कक्षाओं का उपयोग करते हुए, कोई भी व्यक्ति इनवोकेशन विधि की व्यवस्था कर सकता है जैसे:

MakeDelegate<string,int>.WithParams<double>(theDelegate, 3.5);
MakeDelegate<string>.WithParams<int,double>(theDelegate, 7, 5.3);

या, क्योंकि प्रत्येक अभिव्यक्ति में बाद वाले प्रकारों का अनुमान लगाया जा सकता है, भले ही पूर्व वाले न हों:

MakeDelegate<string,int>.WithParams(theDelegate, 3.5);
MakeDelegate<string>.WithParams(theDelegate, 7, 5.3);

नेस्टेड जेनेरिक प्रकारों का उपयोग करना यह बताना संभव बनाता है कि कौन से प्रतिनिधि समग्र प्रकार के विवरण के किन हिस्सों पर लागू होते हैं।


1

नेस्टेड वर्गों का उपयोग निम्नलिखित आवश्यकताओं के लिए किया जा सकता है:

  1. डेटा का वर्गीकरण
  2. जब मुख्य वर्ग का तर्क जटिल होता है और आपको लगता है कि आपको कक्षा का प्रबंधन करने के लिए अधीनस्थ वस्तुओं की आवश्यकता है
  3. जब आप जानते हैं कि कक्षा का राज्य और अस्तित्व पूरी तरह से संलग्न वर्ग पर निर्भर करता है

0

जैसा कि एनफाल ने एब्सट्रैक्ट फैक्ट्री पैटर्न के कार्यान्वयन का उल्लेख किया है, उस कोड को क्लास क्लस्टर्स पैटर्न को प्राप्त करने के लिए जोड़ा जा सकता है जो कि एब्सट्रैक्ट फैक्ट्री पैटर्न पर आधारित है।


0

मुझे ऐसे अपवादों को पसंद है जो एक एकल वर्ग के लिए अद्वितीय हैं, अर्थात। जिन्हें कभी किसी अन्य जगह से नहीं फेंका जाता है।

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

public class MyClass
{
    void DoStuff()
    {
        if (!someArbitraryCondition)
        {
            // This is the only class from which OhNoException is thrown
            throw new OhNoException(
                "Oh no! Some arbitrary condition was not satisfied!");
        }
        // Do other stuff
    }

    public class OhNoException : Exception
    {
        // Constructors calling base()
    }
}

यह आपकी प्रोजेक्ट फाइलों को चुस्त-दुरुस्त रखने में मदद करता है और सौ स्टब्बी से कम अपवाद वाली कक्षाओं से भरा नहीं है।


0

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

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

इसलिए, आप कम जटिलता वाले निजी नेस्टेड वर्गों को लागू करना चाहते हैं।


0

इस मामले के लिए हाँ:

class Join_Operator
{

    class Departamento
    {
        public int idDepto { get; set; }
        public string nombreDepto { get; set; }
    }

    class Empleado
    {
        public int idDepto { get; set; }
        public string nombreEmpleado { get; set; }
    }

    public void JoinTables()
    {
        List<Departamento> departamentos = new List<Departamento>();
        departamentos.Add(new Departamento { idDepto = 1, nombreDepto = "Arquitectura" });
        departamentos.Add(new Departamento { idDepto = 2, nombreDepto = "Programación" });

        List<Empleado> empleados = new List<Empleado>();
        empleados.Add(new Empleado { idDepto = 1, nombreEmpleado = "John Doe." });
        empleados.Add(new Empleado { idDepto = 2, nombreEmpleado = "Jim Bell" });

        var joinList = (from e in empleados
                        join d in departamentos on
                        e.idDepto equals d.idDepto
                        select new
                        {
                            nombreEmpleado = e.nombreEmpleado,
                            nombreDepto = d.nombreDepto
                        });
        foreach (var dato in joinList)
        {
            Console.WriteLine("{0} es empleado del departamento de {1}", dato.nombreEmpleado, dato.nombreDepto);
        }
    }
}

क्यों? भविष्य के पाठकों को आपके उत्तर के पीछे के तर्क को समझने में मदद करने के लिए अपने समाधान के कोड में कुछ संदर्भ जोड़ें।
ग्रांट मिलर

0

इस अवधारणा के बारे में मेरी समझ के आधार पर हम इस सुविधा का उपयोग कर सकते हैं जब कक्षाएं एक दूसरे से वैचारिक रूप से संबंधित हों। मेरा मतलब है कि उनमें से कुछ हमारे व्यवसाय में एक आइटम हैं जैसे कि डीडीडी दुनिया में मौजूद इकाइयाँ जो अपने व्यापार तर्क को पूरा करने के लिए एक मूल जड़ वस्तु की मदद करती हैं।

स्पष्ट करने के लिए मैं इसे एक उदाहरण के माध्यम से दिखाने जा रहा हूँ:

कल्पना कीजिए कि हमारे पास ऑर्डर और ऑर्डर इटेम जैसे दो वर्ग हैं। आदेश वर्ग में, हम सभी ऑर्डर का प्रबंधन करने जा रहे हैं और ऑर्डर इटेम में हम स्पष्टीकरण के लिए एक एकल ऑर्डर के बारे में डेटा रख रहे हैं, आप नीचे कक्षाओं में देख सकते हैं:

 class Order
    {
        private List<OrderItem> _orderItems = new List<OrderItem>();

        public void AddOrderItem(OrderItem line)
        {
            _orderItems.Add(line);
        }

        public double OrderTotal()
        {
            double total = 0;
            foreach (OrderItem item in _orderItems)
            {
                total += item.TotalPrice();
            }

            return total;
        }

        // Nested class
        public class OrderItem
        {
            public int ProductId { get; set; }
            public int Quantity { get; set; }
            public double Price { get; set; }
            public double TotalPrice() => Price * Quantity;
        }
    }

    class Program
    {

        static void Main(string[] args)
        {
            Order order = new Order();

            Order.OrderItem orderItem1 = new Order.OrderItem();
            orderItem1.ProductId = 1;
            orderItem1.Quantity = 5;
            orderItem1.Price = 1.99;
            order.AddOrderItem(orderItem1);

            Order.OrderItem orderItem2 = new Order.OrderItem();
            orderItem2.ProductId = 2;
            orderItem2.Quantity = 12;
            orderItem2.Price = 0.35;
            order.AddOrderItem(orderItem2);

            Console.WriteLine(order.OrderTotal());
            ReadLine();
        }


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