2010-04-29 17 views
11

क्या सी # में नेस्टेड क्लास के तत्कालता को सीमित करने का कोई तरीका है? मैं नेस्टेड क्लास को नेस्टिंग क्लास को छोड़कर किसी भी अन्य वर्ग से तत्काल स्थापित करना चाहता हूं, लेकिन अन्य कोड से नेस्टेड क्लास तक पूर्ण पहुंच की अनुमति देना चाहता हूं।नेस्टेड क्लास कन्स्ट्रक्टर की दृश्यता

+0

लगता है जैसे आप सिंगलटन डिज़ाइन पैटर्न को पुन: पेश कर रहे हैं। –

+0

@ बास्टियान: आपका मतलब है 'कार्यान्वयन'। आप डिज़ाइन पैटर्न का पुन: आविष्कार नहीं करते हैं .... – James

+0

उन सदस्यों को घोषित करें जिन्हें आप एक्सेसरीज़, आंतरिक सहित सुलभ नहीं करना चाहते हैं। यह डिफ़ॉल्ट है। –

उत्तर

27

आमतौर पर मैं उस कार्यक्षमता के लिए एक इंटरफ़ेस बनाता हूं जिसे आप अन्य कक्षाओं में बेनकाब करना चाहते हैं, फिर नेस्टेड क्लास को निजी बनाएं और उस इंटरफ़ेस को कार्यान्वित करें। इस तरह नेस्टेड क्लास परिभाषा छिपी रह सकती है:

public class Outer 
{ 
    private class Nested : IFace 
    { 
     public Nested(...) 
     { 
     } 
     //interface member implementations... 
    } 

    public IFace GetNested() 
    { 
     return new Nested(); 
    } 
} 
6

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

क्या आप का वर्णन कर सकते हैं क्यों आप इस पागल प्रकार की पहुंच चाहते हैं? शायद आप जो चाहते हैं उसे प्राप्त करने का एक बेहतर तरीका है।

+1

मेरे सिर के ऊपर से (क्योंकि यह मेरी चिंता है): IAynyncResult कार्यान्वित करना। –

+0

गलत, मेरा जवाब देखें। – MatteoSp

+6

@MatteoSp: हालांकि मुझे यह खुशी मिलती है कि आपको लगता है कि मैं एक ऐसी सुविधा के बारे में गलत हूं जिसे मैंने कार्यान्वित किया है, मैं आपको आश्वासन देता हूं कि मैं अपने दावे में सही हूं कि कोई अभिगम्यता संशोधक नहीं है जो मूल पोस्टर का विवरण वर्णन करता है। –

-1

अद्यतन: गलत उत्तर, टिप्पणी

देख आंतरिक संशोधक आप के लिए क्या देख रहे है:

public class OuterClass 
{ 
    public class NestedClass { 
     internal NestedClass() 
     { 

     } 
    } 
} 

NestedClass सभी को दिखाई देगा, लेकिन यह निर्माता केवल OuterClass लिए उपलब्ध हो जाएगा है।

+2

यह उत्तर गलत है। यदि आपके पास 'क्लास थर्ड क्लास {शून्य एम() {var x = new OuterClass.NestedClass() है; }} '। याद रखें, मूल पोस्टर चाहता था "* मैं नेस्टेड क्लास को नेस्टिंग क्लास को छोड़कर किसी अन्य वर्ग से तत्काल स्थापित किया जाना चाहता हूं। *" और स्पष्ट रूप से यह बिल में फिट नहीं है। –

+0

हाँ ... आप सही हैं। मैंने नहीं देखा कि मैं एक अलग असेंबली से कन्स्ट्रक्टर का आह्वान करने की कोशिश कर रहा था, यही कारण है कि आंतरिक संशोधक काम कर रहा था ... – MatteoSp

3

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

public class ParentClass 
{ 
    private static Func<FriendClass> _friendContract; 

    public class FriendClass 
    { 
     static FriendClass() 
     { 
      _friendContract=() => new FriendClass(); 
     } 

     private FriendClass() { } 
    } 

    ///Usage 
    public FriendClass MethodUse() 
    { 
     var fInstance = _friendContract(); 
     //fInstance.DoSomething(); 
     return fInstance; 
    } 
} 
बेशक

क्या आप में से एक को पूरा करने की जरूरत है विभिन्न मापदंडों

private static Func<Arg1,Arg2,FriendClass> _friendContract; 
+0

मेरे लिए आंतरिक वर्ग के स्थिर निर्माता को कॉल नहीं किया जाता है और मुझे एक nullreferenceexception –

4

को संभालने के लिए अनुबंध समायोजित कर सकते हैं निम्न आवश्यकताओं:

  • आप नेस्टेड वर्ग सील किया जा करना चाहते हैं,
  • आप सभी नेस्टेड वर्ग के मीटर नकल नहीं करना चाहते Lee's answer में की तरह एक अंतरफलक के लिए ethod हस्ताक्षर,

मैं एक समाधान the one posted by ak99372 के समान पाया है, लेकिन एक स्थिर प्रारंभकर्ता का उपयोग किए बिना:

public class Outer 
{ 
    private interface IPrivateFactory<T> 
    { 
     T CreateInstance(); 
    } 

    public sealed class Nested 
    { 
     private Nested() { 
      // private constructor, accessible only to the class Factory. 
     } 

     public class Factory : IPrivateFactory<Nested> 
     { 
      Nested IPrivateFactory<Nested>.CreateInstance() { return new Nested(); } 
     } 
    } 

    public Nested GetNested() { 
     // We couldn't write these lines outside of the `Outer` class. 
     IPrivateFactory<Nested> factory = new Nested.Factory(); 
     return factory.CreateInstance(); 
    } 
} 

विचार है कि Nested वर्ग के निर्माता केवल के लिए सुलभ है है Factory कक्षा, जो एक स्तर गहराई से घिरा हुआ है। Factory कक्षा निजी इंटरफ़ेस IPrivateFactory से विधि CreateInstance विधि को स्पष्ट रूप से लागू करती है, ताकि केवल IPrivateFactory देख सकें जो CreateInstance पर कॉल कर सकते हैं और Nested का नया उदाहरण प्राप्त कर सकते हैं।

कोड Outer वर्ग स्वतंत्र रूप से Outer.GetNested() पूछे बिना Nested का उदाहरण बना नहीं कर सकते बाहर है, क्योंकि

  1. Outer.Nested के निर्माता privated है, तो वे इसे सीधे
  2. Outer.Nested.Factory instantiated जा सकती है कॉल नहीं कर सकते , लेकिन IPrivateFactory पर नहीं डाला जा सकता है, इसलिए इसकी CreateInstance() विधि को कॉल नहीं किया जा सकता है।

ध्यान दें कि मैं उत्पादन कोड में उस पैटर्न का उपयोग करने की अनुशंसा नहीं करता हूं, लेकिन यह एक चाल है जिसे दुर्लभ मौकों पर मेरी आस्तीन उठाने में उपयोगी लगता है।

1

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

+0

मिलना चाहिए एक नया उत्तर पोस्ट करने के बजाय जोशुआ का जवाब टिप्पणी करें जो वास्तव में एक नहीं है। –

0
public class Outer 
{ 
    public class Nested 
    { 
     readonly Outer Outer; 

     public Nested(Outer outer /* , parameters */) 
     { 
      Outer = outer; 

      // implementation 
     } 

     // implementation 
    } 

    public Nested GetNested(/* parameters */) => new Nested(this /* , parameters */); 
} 

ध्यान दें कि आप नेस्टेड से बाहरी के सदस्यों को एक्सेस कर सकते हैं।

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