2010-03-13 5 views
8

मैं हाल ही में कुछ प्रोग्रामिंग कर रहा है 'और एक मुद्दा है जो मैं सी # में अजीब पाया सामना करना पड़ा। (कम से कम मेरे लिए)छिपे हुए कन्स्ट्रक्टर के साथ नेस्टेड क्लास सी # में असंभव है?

public class Foo 
{ 
    //whatever 
    public class FooSpecificCollection : IList<Bar> 
    { 
     //implementation details 
    } 
    public FooSpecificCollection GetFoosStuff() 
    { 
     //return the collection 
    } 
} 

मैं फू के उपभोक्ता FooSpecificCollection के लिए एक संदर्भ प्राप्त, यहां तक ​​कि उस पर कुछ कार्रवाई करने के लिए सक्षम होना चाहता हूँ। हो सकता है कि इसे फू की किसी अन्य संपत्ति पर भी सेट करें या उस तरह की smth, लेकिन इस वर्ग का एक उदाहरण बनाने में सक्षम नहीं है। (एकमात्र वर्ग जो इस संग्रह को स्थापित करने में सक्षम होना चाहिए, वह होना चाहिए।

क्या मेरा अनुरोध वास्तव में दूरगामी है? मुझे पता है कि लोग समझदार तरीके से परिभाषित सी # हैं लेकिन ऐसा कोई विकल्प नहीं होना चाहिए जो माता-पिता वर्ग अब तक एक नेस्टेड वर्ग उदाहरण बना सकते हैं, लेकिन किसी और नहीं कर सकता।

मैं एक अमूर्त वर्ग, या संपत्ति के माध्यम से उपलब्ध इंटरफ़ेस बनाने के लिए और एक ठोस निजी वर्ग कि कहीं और उपलब्ध नहीं है लागू करने के लिए एक समाधान बनाया।

क्या ऐसी स्थिति को संभालने का यह सही तरीका है।

+0

संभव डुप्लिकेट: http://stackoverflow.com/questions/1664793/how-to-restrict-access-to-nested-class-member-to-enclosing-class –

+0

यह बाहरी वर्ग भर्ती कर सकता है उत्सुक: क्या यह मामला 'फू' के कई उदाहरण होंगे, प्रत्येक के अपने अद्वितीय 'FooSpecificCollection के साथ? – BillW

+0

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

उत्तर

4

तरह से एम्बेडेड वर्गों काम है कि वे बाहरी वर्ग के सदस्य के रूप में, कि बाहरी वर्ग की निजी सदस्यों तक पहुँच प्राप्त है। लेकिन दूसरी तरफ नहीं (आप क्या चाहते हैं)।

आप FooSpecificCollection के निर्माता को ढाल सकते हैं, लेकिन फिर फैक्ट्री को FooSpecificCollection का हिस्सा होना चाहिए।

public class Foo 
{ 
    public class FooSpecificCollection : List<Bar> 
    { 
     private FooSpecificCollection() { } 

     public static FooSpecificCollection GetFoosStuff() 
     { 
      var collection = new FooSpecificCollection(); 
      PrepareFooSpecificCollection(collection); 
      return collection;    
     } 
    } 

    private static void PrepareFooSpecificCollection(FooSpecificCollection collection) 
    { 
     //prepare the collection 
    } 
} 
+0

शायद आप सही हैं :) यह फैक्ट्री पैटर्न जैसा दिखता है (मैंने वास्तव में इसके बारे में सोचा था)। – luckyluke

+0

हमेशा अपने उत्तरों से कुछ सीखें, धन्यवाद, हेनक। इस मामले में क्या होता है यदि 'फू' के कई उदाहरण हैं? – BillW

+1

@ बिलवा, यदि आप वास्तव में इस पैटर्न का उपयोग करना चाहते हैं तो आपको शायद GetFooStuff() और PrepareFooSpecificCollection() पर Foo का एक उदाहरण पास करना होगा। –

3

यदि आप cre हैं दूसरों के उपयोग के लिए लाइब्रेरी में, आप कन्स्ट्रक्टर internal बना सकते हैं। पुस्तकालय के बाहर कोई भी इसे एक्सेस करने में सक्षम नहीं होगा। यदि आप अपने स्वयं के प्रोजेक्ट में कन्स्ट्रक्टर को कॉल करने के बारे में चिंतित हैं, तो बस इसे मूल वर्ग के बाहर कॉल न करें।

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

0

नहीं है, और यह वास्तव में कोई मतलब नहीं है।

मेरा मतलब है पूरे मुद्दे इतना है कि आप संभावित रूप से अन्य उदाहरण लौट सकता है, लेकिन वैसे भी उस वर्ग से कौन होगा? निश्चित रूप से नहीं किसी अन्य वर्गों (क्योंकि वह गलत होगा, और मतलब यह मुख्य वर्ग के अंदर छिपा हुआ नहीं होना चाहिए), इसलिए ...

+0

मैं नेस्टेड क्लास में कुछ कार्यक्षमता रखना चाहता हूं जो पढ़ने और उपयोग करने के लिए स्पष्ट और संक्षेप में है (भोजन के कुछ आंतरिक संग्रह पर पूर्व अच्छा इंटरफ़ेस)। और मैं लोगों को उस वर्ग को बनाने नहीं देना चाहता हूं। बेशक उनके पास वैसे भी कोई व्यवसाय नहीं होना चाहिए, लेकिन मैं अभी भी एक स्पष्ट अर्थशास्त्र चाहता हूं जो कहता है - यह कक्षा आपको कुछ फू की सामग्री पर काम करने में मदद करती है, लेकिन फू इसे भी आपको देता है और आपको इसे स्वयं नहीं बनाना चाहिए ... आंतरिक असेंबली में ठीक है, लेकिन मुझे आपका जवाब नहीं मिला है कि यह क्यों संवेदना नहीं करता है। मैं चाहता हूं कि एक डेवलपर मेरी कक्षा का उपयोग करके इसे तुरंत चालू न करें ... वह मूर्ख क्यों है? – luckyluke

+0

यहां व्युत्पन्न कक्षाओं की तुलना में अन्य चिंताएं हैं। –

+0

luckyluke: तो कन्स्ट्रक्टर निजी बनाओ? मैंने सोचा था कि आप बाहरी वर्ग को इसके उदाहरण बनाने से रोकने की कोशिश कर रहे थे। –

4

अपने नेस्टेड वर्ग private करें और के बजाय GetFoosStuffIList<Bar> के रिटर्न मान कर FooSpecificCollection

इसके अलावा, वहाँ है कि deriving from List<Bar> is a bug एक अच्छा मौका है।

+0

मैं एक सूची से प्राप्त नहीं हूं foo – luckyluke

+0

क्षमा करें मेरा मतलब था निश्चित रूप से। सूची आंतरिक कार्यान्वयन होगी। लेकिन सवाल यह नहीं है कि सवाल क्या है। लेकिन सतर्कता के लिए धन्यवाद :) – luckyluke

+1

"उत्सुकता से सूची" से प्राप्त होने का मतलब सिर्फ उत्सुक है 'एक बग है "। मैंने लिंक को देखा, लेकिन कुछ भी नहीं मिला जो 'सूची ' से प्राप्त करने में समस्या का संकेत देता है। –

1

एक समाधान है लेकिन मुझे नहीं लगता कि मैं इसे अपने ऐप में उपयोग करूँगा :) विचार यह है कि फूस्पेसिफिक से कक्षा प्राप्त हुई है जो निजी है और केवल फू के अंदर ही उपयोग की जा सकती है लेकिन सार्वजनिक कन्स्ट्रक्टर है, इसलिए फू अपने उदाहरण बना सकते हैं।

public class Foo 
{ 
    //whatever 
    public class FooSpecific 
    { 
     // Protected contructor. 
     protected FooSpecific() 
     { 
     } 

     // All other code in here. 
    } 

    // Private helper class used for initialization. 
    private class FooSpecificInitHelper : FooSpecific 
    { 
     public FooSpecificInitHelper() 
     { 
     } 
    } 

    // Method in foo to create instaces of FooSpecific. 
    private FooSpecific CreateFooSpecific() 
    { 
     return new FooSpecificInitHelper(); 
    } 
} 
संबंधित मुद्दे