2009-12-02 11 views
11

यह हो सकता है बल्कि नौसिखिया सवाल लगता है के माध्यम से सुलभ, लेकिन क्यों विधि Der.B() बेस वर्ग चर के माध्यम से फू सुरक्षित नहीं प्राप्त कर सकते हैं व्याख्या कर सकते हैं? यह मेरे लिए अजीब लग रहा है:सी # संरक्षित सदस्यों आधार वर्ग चर

public class Base 
{ 
    protected int Foo; 
} 

public class Der : Base 
{ 
    private void B(Base b) { Foo = b.Foo; } // Error: Cannot access protected member 

    private void D(Der d) { Foo = d.Foo; } // OK 
} 

धन्यवाद!

उत्तर

22

यह एक अक्सर पूछे जाने वाले प्रश्न है। यह पता लगाने के लिए कि यह अवैध क्यों है, इस बारे में सोचें कि क्या गलत हो सकता है।

मान लीजिए आप एक और व्युत्पन्न वर्ग Frob बेस से प्राप्त किया था। अब आप Frob के Der.B. के उदाहरण को पास करते हैं। क्या आप Der.B से Frob.Foo तक पहुंचने में सक्षम होना चाहिए? नहीं, बिलकुल नहीं। Frob.Foo संरक्षित है; यह केवल फ्रोब और फ्रोब के उप-वर्गों से ही सुलभ होना चाहिए। डर फ्रोब नहीं है और फ्रोब का उप-वर्ग नहीं है, इसलिए इसे फ्रोब के संरक्षित सदस्यों तक पहुंच नहीं मिलती है।

हैं कि स्पष्ट नहीं है, इस विषय पर मेरे लेख देखें:

http://blogs.msdn.com/ericlippert/archive/2005/11/09/491031.aspx

+0

धन्यवाद। अब यह मेरे लिए स्पष्ट है। – Roman

0

परिदृश्य क्या आप पूर्णांक फू के लिए "आंतरिक" का उपयोग करना चाहेंगे कोशिश कर रहे हैं में।

+1

यह नहीं होगा काम करें यदि बी को आधार नहीं दिया गया है तो एक डर नहीं है। –

+0

मुझे पता है कि मैं संरक्षित के बजाय आंतरिक या यहां तक ​​कि सार्वजनिक का उपयोग कर सकता हूं। लेकिन मैं समझना चाहता हूं कि पोस्ट में वर्णित संरक्षित व्यवहार क्यों व्यवहार करते हैं। – Roman

+2

@Roman: क्योंकि संरक्षित केवल व्युत्पन्न वर्ग के लिए दृश्यमान है। एक ही उदाहरण के अंदर। लेकिन आप इसे एक अलग उदाहरण से देखने की कोशिश कर रहे हैं। अगर ऐसा किया जा सकता है, तो संरक्षित बहुत बेकार होगा। –

4

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

+0

+1, लेकिन मुझे अभी भी संदेह है कि "इस तथ्य से आप जो विरासत प्राप्त कर रहे हैं वह अप्रासंगिक है"? क्या यह कल्पना भविष्यवाणी है? – Roman

+0

तथ्य यह है कि आप इससे विरासत में हैं, अगर कोई डर शुरू करता है तो आप इसे एक्सेस कर सकते हैं। इस मामले में आप इसे डेर में डाल सकते हैं और फिर फू तक पहुंच सकते हैं। –

2

सीधे शब्दों में कहें, संरक्षित उप वर्गों के लिए उपयोग की अनुमति देता।

में:

private void B(Base b) { Foo = b.Foo; } 

आप किसी सुरक्षित सदस्य डेर के अपने उदाहरण के लिए पहुँच नहीं है तक पहुँचने का प्रयास कर रहे हैं। अगर यह डेर (इस) के आपके वर्तमान उदाहरण का आधार वर्ग था तो इसकी पहुंच केवल तभी होगी।

private void D(Der d) { Foo = d.Foo; } // OK 

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

+1

मुझे लगता है कि आप कहना चाहते थे: निजी शून्य डी (डर डी) {Foo = d.Foo; } ठीक काम करता है। थोड़ा उलझन में बी/सी आपने कोड की रेखा को डुप्लिकेट किया। – Doug

+0

वूप्स, हाँ, मेरा मतलब दूसरे कोड नमूना की प्रतिलिपि बनाना था। – Ragepotato

2

आप आधार वर्ग में एक स्थिर विधि की घोषणा के द्वारा इस सीमा के आसपास काम कर सकते हैं:

public class Base 
{ 
    protected int Foo; 

    protected static int GetFoo(Base b) 
    { 
     return b.Foo; 
    } 
} 

public class Der : Base 
{ 
    private void B(Base b) { Foo = GetFoo(b); } // OK 
}
संबंधित मुद्दे