C # में, सार्वजनिक, निजी, संरक्षित और कोई एक्सेस संशोधक नहीं होने के बीच क्या अंतर है?


728

मेरे सभी कॉलेज के वर्षों मैं का उपयोग किया गया publicहै, और बीच का अंतर जानना चाहते हैं public, privateऔर protected?

इसके अलावा staticकुछ नहीं होने के विपरीत क्या करता है?

जवाबों:


1007

पहुँच संशोधक

से docs.microsoft.com :

public

प्रकार या सदस्य को उसी विधानसभा या किसी अन्य विधानसभा में किसी अन्य कोड द्वारा एक्सेस किया जा सकता है जो इसे संदर्भित करता है।

private

प्रकार या सदस्य केवल एक ही कक्षा या संरचना में कोड द्वारा पहुँचा जा सकता है।

protected

प्रकार या सदस्य को केवल उसी वर्ग या संरचना में या एक व्युत्पन्न वर्ग में कोड द्वारा पहुँचा जा सकता है।

private protected (C # 7.2 में जोड़ा गया)

प्रकार या सदस्य को केवल उसी वर्ग या संरचना में या उसी विधानसभा से व्युत्पन्न वर्ग में कोड द्वारा पहुँचा जा सकता है, लेकिन किसी अन्य विधानसभा से नहीं।

internal

प्रकार या सदस्य को किसी भी विधानसभा में किसी भी कोड द्वारा पहुँचा जा सकता है, लेकिन किसी अन्य विधानसभा से नहीं।

protected internal

प्रकार या सदस्य को उसी विधानसभा में किसी भी कोड या किसी अन्य विधानसभा में किसी भी व्युत्पन्न वर्ग द्वारा पहुँचा जा सकता है।

जब कोई एक्सेस संशोधक सेट नहीं किया जाता है, तो डिफ़ॉल्ट एक्सेस संशोधक का उपयोग किया जाता है। तो वहाँ हमेशा पहुँच संशोधक के कुछ फार्म है भले ही यह सेट नहीं है।

static संशोधक

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

एक स्थिर वर्ग मूल रूप से एक गैर-स्थिर वर्ग के समान होता है, लेकिन एक अंतर है: एक स्थिर वर्ग बाहरी रूप से त्वरित नहीं हो सकता है। दूसरे शब्दों में, आप वर्ग प्रकार का एक चर बनाने के लिए नए कीवर्ड का उपयोग नहीं कर सकते। कोई उदाहरण चर नहीं होने के कारण, आप स्वयं क्लास नाम का उपयोग करके किसी स्थिर वर्ग के सदस्यों तक पहुँचते हैं।

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

static class Foo()
{
    static Foo()
    {
        Bar = "fubar";
    }

    public static string Bar { get; set; }
}

स्टेटिक क्लासेस को अक्सर सेवाओं के रूप में उपयोग किया जाता है, आप उन्हें इस तरह से उपयोग कर सकते हैं:

MyStaticClass.ServiceMethod(...);

17
और आपके पास गैर-स्थिर कक्षाओं में स्थिर तरीके हो सकते हैं, है ना?
जॉन Bubriski

14
हां, वे उसी तरह व्यवहार करेंगे जैसे मेरे उदाहरण में।
mbillard

7
इस संदर्भ में "असेंबली" शब्द का क्या अर्थ है?
जोनाथन ग्लीसन

1
@gotoVoid आपने Google पर जो कुछ भी खोजा है वह गलत है। MSDN के अनुसार , संरक्षित आंतरिक का मतलब है कि, "जिस प्रकार या सदस्य को विधानसभा में किसी भी कोड द्वारा घोषित किया जाता है, या किसी अन्य विधानसभा में एक व्युत्पन्न वर्ग के भीतर से पहुँचा जा सकता है।"
केविन

2
संरक्षित और निजी संरक्षित के बीच अंतर क्या है? मेरे लिए, ऐसा लगता है कि दोनों एक ही हैं ..
goofyui

161

एक ग्राफिकल ओवरव्यू (संक्षेप में सारांश)

दृश्यता

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



यदि आप कोई एक्सेस संशोधक सामने नहीं रखते हैं, तो डिफ़ॉल्ट के लिए , यहां देखें:
C # कक्षाओं और सदस्यों (फ़ील्ड्स, विधियों आदि) के लिए डिफ़ॉल्ट दृश्यता?

गैर नेस्ट

enum                              public
non-nested classes / structs      internal
interfaces                        internal
delegates in namespace            internal
class/struct member(s)            private
delegates nested in class/struct  private

नेस्ट:

nested enum      public
nested interface public
nested class     private
nested struct    private

इसके अलावा, वे सील-कीवर्ड हैं, जो एक वर्ग को अंतर्निहित नहीं बनाता है।
इसके अलावा, VB.NET में, कीवर्ड कभी-कभी अलग होते हैं, इसलिए यहां एक धोखा-शीट है:

VB बनाम CS समतुल्य


1
@ suren BᴀʀᴜrtiL: क्या आपको यकीन है? एक अलग विधानसभा में एक व्युत्पन्न वर्ग?
स्टीफन स्टीगर

एक ही असेंबली में व्युत्पन्न वर्ग, अलग-अलग हम नहीं कर सकते। मुझे लगा कि आप एक ही असेंबली की तरह हैं ...
अरुण बर्टिल

1
@ ,n BᴀʀᴜrtiL: हम्म, सही, यह वास्तव में रचा जाना चाहिए।
स्टीफन स्टीगर

1
मुझे लगता है कि आरेख में कोई त्रुटि है। यदि किसी वर्ग के लिए आंतरिक का उपयोग किया जाता है, तो कक्षा को उसी विधानसभा में किसी अन्य वर्ग द्वारा प्राप्त किया जा सकता है। इसके अलावा अगर किसी संपत्ति पर आंतरिक संशोधक का उपयोग किया जाता है, तो यह संपत्ति उसी विधानसभा में व्युत्पन्न वर्ग में भी एक्सेस की जा सकती है। शायद आरेख सही है क्योंकि "असेंबली युक्त" के तहत "हां" है, लेकिन इसे गलत समझा जा सकता है क्योंकि "व्युत्पन्न वर्ग" के तहत "नहीं" है।
ए.एच.

160

सार्वजनिक - यदि आप वर्ग देख सकते हैं, तो आप विधि देख सकते हैं

निजी - यदि आप कक्षा का हिस्सा हैं , तो आप विधि देख सकते हैं, अन्यथा नहीं।

संरक्षित - निजी के समान, साथ ही सभी वंशज विधि भी देख सकते हैं।

स्टेटिक (वर्ग) - "क्लास" और "ऑब्जेक्ट" के बीच अंतर को याद रखें? वह सब भूल जाओ। वे "स्थिर" के साथ समान हैं ... वर्ग स्वयं का एक-और उदाहरण है।

स्टेटिक (विधि) - जब भी आप इस विधि का उपयोग करते हैं, तो यह उस कक्षा के वास्तविक उदाहरण से स्वतंत्र संदर्भ का एक फ्रेम होगा जिसका यह हिस्सा है।


1
क्या आपके पास एक गैर स्थिर वर्ग में स्थिर विधियां नहीं हैं?
जॉन Bubriski

1
हां, लेकिन मैं एक स्थिर वर्ग के बारे में बात कर रहा था। मैंने स्थैतिक विधियों का वर्णन करने के लिए एक अलग प्रविष्टि जोड़ी। पकड़ने के लिए धन्यवाद।
जोसेफटाइन्स

2
C # के बारे में बात करते समय 'ऑब्जेक्ट' एक अच्छा शब्द नहीं हो सकता है, क्योंकि सभी वर्गों के लिए आधार-प्रकार System.Object है । 'इंस्टेंस' एक बेहतर शब्द होगा, या 'ऑब्जेक्ट' (लोअरकेस 'ओ')।
15

@lesderid 'ऑब्जेक्ट' 'System.Object' का एक अन्य नाम है, इसका उपयोग करना भी भ्रामक हो सकता है। 'उदाहरण' बेहतर होगा, मुझे लगता है :)
dpp

समान नियम संरचना पर लागू होते हैं।
gsharp

35

इस उत्तर से भयानक आरेखों को फिर से तैयार करना ।

वेन आरेखों में सभी एक्सेस मॉडिफ़ायर हैं, जो अधिक सीमित से अधिक उचित तक हैं:

private:
यहां छवि विवरण दर्ज करें

private protected: - C # 7.2 में जोड़ा गया
यहां छवि विवरण दर्ज करें

internal:
यहां छवि विवरण दर्ज करें

protected:
यहां छवि विवरण दर्ज करें

protected internal:
यहां छवि विवरण दर्ज करें

public:
यहां छवि विवरण दर्ज करें


24

यहां छवि विवरण दर्ज करें

using System;

namespace ClassLibrary1
{
    public class SameAssemblyBaseClass
    {
        public string publicVariable = "public";
        protected string protectedVariable = "protected";
        protected internal string protected_InternalVariable = "protected internal";
        internal string internalVariable = "internal";
        private string privateVariable = "private";
        public void test()
        {
            // OK
            Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(publicVariable);

            // OK
            Console.WriteLine(protectedVariable);

            // OK
            Console.WriteLine(internalVariable);

            // OK
            Console.WriteLine(protected_InternalVariable);
        }
    }

    public class SameAssemblyDerivedClass : SameAssemblyBaseClass
    {
        public void test()
        {
            SameAssemblyDerivedClass p = new SameAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }

    public class SameAssemblyDifferentClass
    {
        public SameAssemblyDifferentClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // NOT OK
            // Console.WriteLine(privateVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            //Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }
}

 using System;
        using ClassLibrary1;
        namespace ConsoleApplication4

{
    class DifferentAssemblyClass
    {
        public DifferentAssemblyClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            // Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protectedVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protected_InternalVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protected_InternalVariable);
        }
    }

    class DifferentAssemblyDerivedClass : SameAssemblyBaseClass
    {
        static void Main(string[] args)
        {
            DifferentAssemblyDerivedClass p = new DifferentAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            //Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);

            SameAssemblyDerivedClass dd = new SameAssemblyDerivedClass();
            dd.test();
        }
    }
}

1
मैं नहीं देखता कि यह उत्तर पिछले पांच वर्षों में कई अन्य उत्तरों से क्या जोड़ता है।
जॉन सॉन्डर्स

4
यह केवल एक सरल व्याख्या है। जैसा कि अन्य उत्तर थोड़ा भ्रमित और आधे उत्तर हैं :)
नरोत्तम गोयल

4
@ जॉन सॉन्डर्स: यह उस वर्ग के बीच एक व्युत्पन्न वर्ग के लिए दृश्यता को अलग करके अलग करता है और उस वर्ग को एक अलग विधानसभा में होता है। साथ ही वह यह जानकारी प्रदान करता है कि उसने अपना नमूना कोड दिखाकर उस जानकारी को कैसे प्राप्त किया। इसलिए यह वास्तव में अन्य उत्तरों को जोड़ता है। मेरे जवाब में मेरी टिप्पणी से उसका परिहास शायद शुरू हो गया था।
स्टीफन स्टीगर

2
"विभिन्न विधानसभा में व्युत्पन्न वर्ग" - यह दूसरे उत्तर में पहले से दिए गए चार्ट के लिए मूल्य जोड़ता है। अंतर विशेष रूप से की "आंतरिक संरक्षित" मामले में सहायक है
निर्माण

मुझे समझने के लिए यह चार्ट सबसे आसान लगता है। इस धारा को रखने के लिए (सी # 7.2 के साथ), जोड़ने के लिए Private Protected, यह होगा: एक ही वर्ग = Yes, एक ही विधानसभा, व्युत्पन्न वर्ग = Yes, एक ही विधानसभा, कोई वर्ग = NO, अलग-अलग विधानसभा, व्युत्पन्न वर्ग = NO, अलग-अलग विधानसभा, कोई भी वर्ग = NO। एक अतिरिक्त सुझाव यह भी होगा कि इसके लिए वर्ड ऑर्डर को स्विच न किया जाए protected internal, क्योंकि यह @18188787 के उत्तर से न्यूमोनिक को तोड़ता है
Intrastellar Explorer

22

कुछ नहीं के सवाल के बारे में

  • नाम प्रकार डिफ़ॉल्ट रूप से आंतरिक हैं
  • किसी भी प्रकार का सदस्य, जिसमें नेस्टेड प्रकार शामिल हैं, डिफ़ॉल्ट रूप से निजी हैं

15

फिर भी वर्तमान पहुंच संशोधक का एक और दृश्य दृष्टिकोण (सी # 7.2)। उम्मीद है कि स्कीमा इसे आसान याद रखने में मदद करती है
(इंटरेक्टिव दृश्य के लिए छवि पर क्लिक करें)

इंटरैक्टिव एक्सेस मॉडिफ़ायर svg

बाहर अंदर

यदि आप दो-शब्द एक्सेस मॉडिफायर को याद करने के लिए संघर्ष करते हैं, तो बाहर-अंदर याद रखें ।

  • निजी संरक्षित : निजी बाहर (एक ही विधानसभा) अंदर संरक्षित (एक ही विधानसभा)
  • संरक्षित आंतरिक : बाहर संरक्षित (एक ही विधानसभा) आंतरिक अंदर (एक ही विधानसभा)

11

हम्म।

यहाँ देखें: पहुँच संशोधक

संक्षेप में:

जनता अन्य प्रकार / वर्गों से पूर्ण दृश्यता की विधि या प्रकार देती है।

निजी केवल निजी पद्धति / वैरिएबल एक्सेस के लिए निजी विधि / वैरिएबल युक्त प्रकार की अनुमति देता है (ध्यान दें कि नेस्टेड क्लासेस की भी निजी क्लासेस / वैरिएबल तक पहुँच होती है)।

संरक्षित निजी समान है सिवाय व्युत्पन्न वर्ग भी संरक्षित विधियों का उपयोग कर सकते हैं।

"कुछ नहीं" शून्य के बराबर VB.NET है। यद्यपि यदि आप "कुछ भी नहीं" का अर्थ "कोई एक्सेस संशोधक" नहीं कर रहे हैं, तो यह निर्भर करता है, हालांकि अंगूठे का एक बहुत मोटा नियम (निश्चित रूप से सी # में) यह है कि यदि आप स्पष्ट रूप से एक पहुंच संशोधक निर्दिष्ट नहीं करते हैं, तो विधि / चर घोषणा आम तौर पर प्रतिबंधित होती है क्योंकि यह हो सकती है। अर्थात

public class MyClass
{
    string s = "";
}

प्रभावी रूप से समान है:

public class MyClass
{
    private string s = "";
}

लिंक किए गए MSDN आलेख पूरी तरह से विवरण प्रदान करेगा जब कोई एक्सेस संशोधक स्पष्ट रूप से निर्दिष्ट नहीं है।


8

सार्वजनिक - कहीं भी किसी के द्वारा भी पहुँचा जा सकता है।
निजी - को केवल उसी वर्ग से प्राप्त किया जा सकता है जिसका वह हिस्सा है।
संरक्षित - केवल कक्षा या किसी भी ऑब्जेक्ट से प्राप्त किया जा सकता है जो कक्षा से विरासत में मिला है।

शून्य जैसा कुछ भी नहीं है लेकिन वीबी में।
स्टेटिक का मतलब है कि आपके पास उस ऑब्जेक्ट का एक उदाहरण है, उस वर्ग के हर उदाहरण के लिए विधि।


4

mmm ...

स्टेटिक का अर्थ है कि आप उस फ़ंक्शन को कक्षा का उदाहरण दिए बिना एक्सेस कर सकते हैं।

आप सीधे कक्षा की परिभाषा से पहुँच सकते हैं।


4

निजी की स्थिति इंगित करती है कि चर केवल उसी वर्ग की वस्तुओं द्वारा पहुँचा जा सकता है। संरक्षित स्थिति का उपयोग उस वर्ग के वंशजों को भी शामिल करने के लिए किया जाता है।

"उपरोक्त सारणी से हम निजी और संरक्षित के बीच के टकराव को देख सकते हैं ... मुझे लगता है कि दोनों समान हैं .... इसलिए उस दो अलग-अलग सेनाओं की क्या आवश्यकता है"

अधिक जानकारी के लिए MSDN लिंक की जाँच करें


3

वे एक्सेस मॉडिफ़ायर निर्दिष्ट करते हैं जहां आपके सदस्य दिखाई देते हैं। आपको शायद इसे पढ़ना चाहिए। IainMH द्वारा दिए गए लिंक को शुरुआती बिंदु के रूप में लें।

स्टैटिक सदस्य एक प्रति वर्ग हैं और एक प्रति उदाहरण नहीं।


3

सावधानी से अपनी कक्षाओं की अपनी पहुंच देखें। सार्वजनिक और संरक्षित कक्षाएं और विधियां डिफ़ॉल्ट रूप से सभी के लिए सुलभ हैं।

जब दृश्य स्टूडियो में नई कक्षाएं बनाई जाती हैं, तो Microsoft एक्सेस मॉडिफायर (सार्वजनिक, संरक्षित, आदि) कीवर्ड दिखाने में बहुत अधिक अन्वेषण नहीं करता है। इसलिए, अच्छी तरह से देखभाल करें और अपनी कक्षा की अपनी पहुंच के बारे में सोचें क्योंकि यह आपके कार्यान्वयन इंटर्न्स का द्वार है।


2

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


1

C # में कुल 6 हैं पहुंच संशोधक हैं:

निजी : इस एक्सेसिबिलिटी के साथ घोषित सदस्य को प्रकार के भीतर दिखाई दे सकता है, यह किसी भी व्युत्पन्न प्रकार, उसी विधानसभा में अन्य प्रकार या युक्त विधानसभा के बाहर दिखाई नहीं देता है। यानी, एक्सेस केवल टाइपिंग तक ही सीमित है।

संरक्षित : इस एक्सेसिबिलिटी के साथ घोषित सदस्य को असेंबली के अंदर टाइपिंग के प्रकार से, और असेंबली से बाहर के प्रकार से व्युत्पन्न प्रकार से दिखाई दे सकता है। अर्थात्, पहुँच युक्त प्रकारों तक सीमित है।

अंदर का : इस पहुंच के साथ घोषित सदस्य इस सदस्य वाली विधानसभा के भीतर दिखाई दे सकता है, यह विधानसभा के बाहर किसी भी विधानसभा को दिखाई नहीं देता है। यानी, एक्सेस केवल असेंबली रखने तक सीमित है।

आंतरिक संरक्षित : इस पहुंच के साथ घोषित सदस्य को विधानसभा के भीतर या उसके बाहर वाले प्रकार से व्युत्पन्न प्रकारों के भीतर दिखाई दे सकता है, यह किसी भी प्रकार के विधानसभा के भीतर दिखाई देता है। अर्थात्, पहुंच विधानसभा या व्युत्पन्न प्रकारों तक सीमित है।

सार्वजनिक : इस पहुंच के साथ घोषित सदस्य इस सदस्य वाली विधानसभा के भीतर दिखाई दे सकता है, या कोई अन्य विधानसभा जिसमें विधानसभा शामिल है। यानी, पहुंच सीमित नहीं है।

C # 7.2 पहुंच का एक नया स्तर जोड़ रहा है:

निजी संरक्षित : इस पहुँच के साथ घोषित सदस्य इस प्रकार से लिया जा सकता है जिसमें इस प्रकार के विधानसभा से शामिल हैं। यह किसी भी प्रकार से नहीं दिखाई देता है जिसमें शामिल प्रकार से, या विधानसभा से बाहर नहीं है। यानी, पहुंच विधानसभा वाले प्रकारों तक सीमित है।

नया निजी संरक्षित एक्सेस संशोधक का एक नमूना कोड सहित स्रोत


0

C # के लिए सभी एक्सेस संशोधक का वर्णन

यहां छवि विवरण दर्ज करें

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