(C#7.2) "निजी संरक्षित" संशोधक के लिए उपयोग का मामला क्या है?




.net access-modifiers (3)

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

संरक्षित आंतरिक

  • एक और विधानसभा में संरक्षित : केवल बाल वर्गों में ही सुलभ।

  • वर्तमान विधानसभा में आंतरिक : वर्तमान विधानसभा में सभी के लिए सुलभ।

निजी संरक्षित

  • अन्य विधानसभा में निजी : सुलभ नहीं है।
  • वर्तमान विधानसभा में संरक्षित : केवल बाल वर्गों में ही सुलभ।

C # 7.2 निजी संरक्षित संशोधक का परिचय देता है

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

मैं यह समझने की कोशिश कर रहा हूं कि C # भाषा टीम ने इस सुविधा को क्यों जोड़ा है। Google पर एक व्यापक खोज के बाद, और 'व्हाट्स न्यू' मीडिया को पढ़ना और देखना (मैंने प्रेस रिलीज , details और वीडियो मैडस टॉरगर्सन द्वारा देखा है), मैं अभी भी समझदार नहीं हूं।

मेरे लिए, यह एक डेवलपर को Liskov प्रतिस्थापन सिद्धांत को तोड़ने की अनुमति देने के लिए प्रकट होता है, लेकिन ऐसा इसलिए हो सकता है क्योंकि मुझे समझ नहीं आता कि यह सुविधा क्यों मौजूद है।

मैं समझता हूं कि इसका उपयोग कैसे किया जा सकता है, बस क्यों नहीं - कृपया कोई व्यक्ति MSDN दस्तावेज़ों में से एक के बजाय एक वास्तविक दुनिया उपयोग उदाहरण प्रदान कर सकता है?


मान लीजिए कि आपके पास एक आंतरिक वर्ग है जिसे कुछ SomeHelper कहा जाता है जिसे आप एक सार्वजनिक SomeHelper आधार के कार्यान्वयन के हिस्से के रूप में उपयोग करना चाहते हैं:

public abstract class Test
{
    // Won't compile because SomeHelper is internal.
    protected SomeHelper CreateHelper()
    {
        return new SomeHelper();
    }

    public int Func(int x)
    {
        var helper = CreateHelper();
        return helper.DoSomething(x);
    }
}

internal class SomeHelper
{
    public virtual int DoSomething(int x)
    {
        return -x;
    }
}

यह संकलित नहीं करेगा क्योंकि आपके पास एक आंतरिक प्रकार लौटाने वाली एक संरक्षित विधि नहीं हो सकती है। आपका एकमात्र सहारा किसी तरह से कुछ SomeHelper का उपयोग नहीं करना है, न ही कुछ SomeHelper सार्वजनिक करना है।

(आप कुछ SomeHelper को Test की संरक्षित आंतरिक श्रेणी बना सकते हैं, लेकिन यह काम करने वाला नहीं है अगर कुछ SomeHelper को अन्य वर्गों द्वारा उपयोग करने का इरादा है जो बेस क्लास से नहीं निकलते हैं।)

private protected सुविधा की शुरुआत के साथ, आप CreateHelper() को घोषित कर सकते हैं:

private protected SomeHelper CreateHelper()
{
    return new SomeHelper();
}

अब यह संकलन करेगा, और आपको अपने इंटर्न को उजागर करने की आवश्यकता नहीं है।


C # 7.2 से पहले हमने protected internal संशोधक की protected internal थी। यह वास्तव में संरक्षित या आंतरिक का मतलब है, वह है - सदस्य A बाल वर्गों के लिए और वर्तमान विधानसभा में किसी भी वर्ग के लिए सुलभ है, भले ही वह वर्ग A का बच्चा न हो (इसलिए "संरक्षित" द्वारा निहित प्रतिबंध आराम है)।

private protected वास्तव में संरक्षित और आंतरिक का मतलब है। वह है - सदस्य केवल उन बाल वर्गों के लिए सुलभ है, जो एक ही विधानसभा में हैं, लेकिन उन बाल वर्गों के लिए नहीं हैं जो विधानसभा के बाहर हैं (इसलिए "संरक्षित" द्वारा निहित प्रतिबंध संकुचित है - और भी अधिक प्रतिबंधक हो जाता है)। यदि आप अपनी विधानसभा में कक्षाओं के पदानुक्रम का निर्माण करते हैं और उस संयोजन के कुछ हिस्सों तक पहुँचने के लिए अन्य विधानसभाओं से कोई बाल वर्ग नहीं चाहते हैं तो यह उपयोगी है।

हम उदाहरण दे सकते हैं कि जॉन स्कीट ने टिप्पणियों में प्रदान किया था । मान लीजिए आपके पास क्लास है

public class MyClass {

}

और आप इसे केवल वर्तमान विधानसभा में विरासत में प्राप्त करने में सक्षम होना चाहते हैं, लेकिन इस वर्ग पदानुक्रम के अलावा इस वर्ग को तुरंत अनुमति नहीं देना चाहते हैं।

केवल वर्तमान विधानसभा के भीतर प्रवेश करने से आंतरिक निर्माणकर्ता को प्राप्त किया जा सकता है

public class MyClass {
    internal MyClass() {
    }
}

वर्तमान श्रेणी के पदानुक्रम को छोड़कर सीधे तात्कालिकता को रोकना संरक्षित कंस्ट्रक्टर के साथ प्राप्त किया जा सकता है:

public class MyClass {
    protected MyClass() {
    }
}

और दोनों प्राप्त करने के लिए - आपको private protected निर्माता की आवश्यकता है:

public class MyClass {
    private protected MyClass() {
    }
}






c#-7.2