2009-12-15 19 views
12

मैं हाल ही में पता चला कि एक व्युत्पन्न वर्ग में एक विधि केवल व्युत्पन्न वर्ग का एक उदाहरण के माध्यम से आधार वर्ग के संरक्षित उदाहरण सदस्यों तक पहुँच सकते हैं (या उसके उपवर्गों में से एक):आधार/भाई वर्ग के माध्यम से संरक्षित सदस्य पहुंच को रोकने के लिए वास्तविक कारण क्या है?

class Base 
{ 
    protected virtual void Member() { } 
} 

class MyDerived : Base 
{ 
    // error CS1540 
    void Test(Base b) { b.Member(); } 
    // error CS1540 
    void Test(YourDerived yd) { yd.Member(); } 

    // OK 
    void Test(MyDerived md) { md.Member(); } 
    // OK 
    void Test(MySuperDerived msd) { msd.Member(); } 
} 

class MySuperDerived : MyDerived { } 

class YourDerived : Base { } 

मैं इस प्रतिबंध को हल करने के करने में कामयाब बेस क्लास में स्थिर विधि जोड़कर, बेस की विधियों को बेस.मेम्बर तक पहुंचने की अनुमति है, और MyDerived उस स्थिर विधि को कॉल कर सकते हैं।

हालांकि मैं अभी भी इस सीमा के कारण को समझ नहीं पा रहा हूं। मैंने कुछ अलग स्पष्टीकरण देखा है, लेकिन वे यह समझाने में नाकाम रहे कि MyDerived.Test() को अभी भी MySuperDerived तक पहुंचने की अनुमति है। मेम्बर।

प्रिंसिपल स्पष्टीकरण: 'संरक्षित' का अर्थ है कि यह केवल उस वर्ग और इसके उप-वर्गों के लिए सुलभ है। YourDerived सदस्य() को ओवरराइड कर सकता है, एक नई विधि बना रहा है जो केवल आपके डेरिवेट और इसके उप-वर्गों तक पहुंच योग्य हो। MyDerived ओवरराइड yd.Member() को कॉल नहीं कर सकता क्योंकि यह आपके Derived का उप-वर्ग नहीं है, और यह b.Member() को कॉल नहीं कर सकता है क्योंकि बी वास्तव में आपके Derived का उदाहरण हो सकता है।

ठीक है, लेकिन फिर MyDerived कॉल msd.Member() क्यों कर सकता है? MySuperDerived सदस्य() को ओवरराइड कर सकता है, और ओवरराइड केवल MySuperDerived और इसके उप-वर्गों तक पहुंच योग्य होना चाहिए, है ना?

आप वास्तव में रनटाइम तक नहीं जानते हैं कि आप एक ओवरराइड सदस्य को कॉल कर रहे हैं या नहीं। और जब सदस्य एक क्षेत्र होता है, तो इसे किसी भी तरह से ओवरराइड नहीं किया जा सकता है, लेकिन पहुंच अभी भी प्रतिबंधित है।

व्यावहारिक स्पष्टीकरण: अन्य कक्षाएं उन वर्गों को जोड़ सकती हैं जिन्हें आपकी कक्षा के बारे में पता नहीं है, और आपको उनके सार्वजनिक इंटरफ़ेस का उपयोग करना चाहिए ताकि वे उन आविष्कारों को बनाए रख सकें। यदि MyDerived सीधे आपके डेरिवेट के संरक्षित सदस्यों तक पहुंच सकता है, तो यह उन आविष्कारों को तोड़ सकता है।

मेरा वही आपत्ति यहां लागू होता है। MyDerived को पता नहीं है कि MySuperDerived क्या जोड़ सकता है, या तो - इसे किसी भिन्न लेखक द्वारा एक अलग असेंबली में परिभाषित किया जा सकता है - तो MyDerived सीधे अपने संरक्षित सदस्यों तक क्यों पहुंच सकता है?

मुझे लगता है कि यह संकलन-समय सीमा एक समस्या को हल करने के लिए एक गुमराह प्रयास के रूप में मौजूद है जो वास्तव में केवल रनटाइम पर हल हो सकती है। लेकिन शायद मुझे कुछ याद आ रहा है। क्या किसी के पास किसी समस्या का उदाहरण है जो MyDerived को बेस के संरक्षित सदस्यों को आपके डीरियोजित या बेस के प्रकार के माध्यम से एक्सेस करने के कारण होगा, लेकिन पहले से मौजूद नहीं है जब वे MyDerived या MySuperDerived प्रकार के चर के माध्यम से उन्हें एक्सेस करते हैं?

-

अद्यतन: मैं जानता हूँ कि संकलक सिर्फ भाषा विनिर्देश पीछा कर रहा है; जो मैं जानना चाहता हूं वह कल्पना के उस हिस्से का उद्देश्य है। एक आदर्श उत्तर इस तरह होगा, "अगर माईड्राइव आपका कॉलरिवेट कॉल कर सकता है। मेम्बर(), $ नाइटमेयर होगा, लेकिन यह MySuperDerived को कॉल करते समय नहीं हो सकता है। मेम्बर() क्योंकि $ ITSALLGOOD।"

+0

एरिक लिपर्ट की पोस्ट पढ़ने के बाद, मुझे उत्सुकता है कि उसकी व्याख्या में कमी आई थी। एक स्थिर विश्लेषण में संकलक उस जानकारी को कैसे जान सकता है जिसे आप जानते हैं? मैं उत्सुक हूं कि इस समस्या को हल करने के लिए संविधान या contravariance, इसीलिए यह एक टिप्पणी है और जवाब नहीं है। –

+0

मुझे कोई तरीका नहीं दिखता है कि भिन्नता यहां प्रासंगिक हो जाती है। क्या आप विस्तार कर सकते हैं कि आपको ऐसा क्यों लगता है? –

+0

एरिक का ब्लॉग पोस्ट कहता है, "हम अनग्युलेट को कॉल कर सकते हैं। कानूनी रूप से जिराफ से खाएं, लेकिन हम सुरक्षित विधि ज़ेबरा को नहीं बुला सकते हैं। ज़ेबरा या ज़ेबरा के उप-वर्ग को छोड़कर कुछ भी खाएं।" यह मुझे स्पष्ट नहीं था * क्यों * हम जिराफ को ज़ेबरा को फोन करने से रोकना चाहते हैं। हालांकि, इसे अभी भी SubclassOfGiraffe.Eat पर कॉल करने की इजाजत है। यदि प्रतिबंध वास्तविक प्रकार पर आधारित था ("जिराफ केवल जिराफ के उदाहरणों पर खा सकता है"), मैं संकलक को जानने की अपेक्षा नहीं करता; इसे रनटाइम पर लागू किया जाना होगा। –

उत्तर

17

अद्यतन: यह सवाल जनवरी 2010 में मेरे ब्लॉग का विषय था। महान प्रश्न के लिए धन्यवाद! देखें:

https://blogs.msdn.microsoft.com/ericlippert/2010/01/14/why-cant-i-access-a-protected-member-from-a-derived-class-part-six/


है किसी को भी एक समस्या यह है कि वजह से हो जाएगा द्वारा दे प्रकार YourDerived या बेस के एक चर के माध्यम से पहुँच बेस के संरक्षित सदस्यों MyDerived का एक उदाहरण है, लेकिन करता है पहले से मौजूद नहीं है जब उन्हें का उपयोग MyDerived या MySuperDerived प्रकार के चर के माध्यम से किया जा रहा है?

मैं आपके प्रश्न से उलझन में हूं लेकिन मैं इसे एक शॉट देने के लिए तैयार हूं।

यदि मैं इसे सही ढंग से समझता हूं, तो आपका प्रश्न दो भागों में है। सबसे पहले, हमले की कमी कम-व्युत्पन्न प्रकार के माध्यम से संरक्षित तरीकों को कॉल करने पर प्रतिबंध को उचित ठहराती है? दूसरा, समान औचित्य समान रूप से व्युत्पन्न या अधिक व्युत्पन्न प्रकारों पर संरक्षित तरीकों से कॉल को रोकने के लिए प्रेरित क्यों नहीं करता है?

पहले भाग स्पष्ट है:

// Good.dll: 

public abstract class BankAccount 
{ 
    abstract protected void DoTransfer(BankAccount destinationAccount, User authorizedUser, decimal amount); 
} 

public abstract class SecureBankAccount : BankAccount 
{ 
    protected readonly int accountNumber; 
    public SecureBankAccount(int accountNumber) 
    { 
    this.accountNumber = accountNumber; 
    } 
    public void Transfer(BankAccount destinationAccount, User user, decimal amount) 
    { 
    if (!Authorized(user, accountNumber)) throw something; 
    this.DoTransfer(destinationAccount, user, amount); 
    } 
} 

public sealed class SwissBankAccount : SecureBankAccount 
{ 
    public SwissBankAccount(int accountNumber) : base(accountNumber) {} 
    override protected void DoTransfer(BankAccount destinationAccount, User authorizedUser, decimal amount) 
    { 
    // Code to transfer money from a Swiss bank account here. 
    // This code can assume that authorizedUser is authorized. 

    // We are guaranteed this because SwissBankAccount is sealed, and 
    // all callers must go through public version of Transfer from base 
    // class SecureBankAccount. 
    } 
} 

// Evil.exe: 

class HostileBankAccount : BankAccount 
{ 
    override protected void Transfer(BankAccount destinationAccount, User authorizedUser, decimal amount) { } 

    public static void Main() 
    { 
    User drEvil = new User("Dr. Evil"); 
    BankAccount yours = new SwissBankAccount(1234567); 
    BankAccount mine = new SwissBankAccount(66666666); 
    yours.DoTransfer(mine, drEvil, 1000000.00m); // compilation error 
    // You don't have the right to access the protected member of 
    // SwissBankAccount just because you are in a 
    // type derived from BankAccount. 
    } 
} 

डॉ बुराई के अपने स्विस बैंक खाते से चोरी करने के लिए एक ... लाख ... डॉलर ... प्रयास सी # संकलक ने नाकाम कर दिया गया है।

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

लेकिन मेरा मुद्दा यह है कि यहां "हमला" जो फॉइल किया गया है, कोई है जो सुरक्षित रूप से स्विसबैंक अकाउंट में कोड तक पहुंचने के लिए सिक्योरबैंक अकाउंट द्वारा स्थापित इनवेरिएंट के आसपास एक अंत-दौड़ करने का प्रयास कर रहा है।

यह आपके पहले प्रश्न का उत्तर देता है, मुझे उम्मीद है। यदि यह स्पष्ट नहीं है, तो मुझे बताएं।

आपका दूसरा सवाल यह है कि "सिक्योरबैंक अकाउंट में यह प्रतिबंध क्यों नहीं है?" मेरे उदाहरण में, SecureBankAccount का कहना है:

this.DoTransfer(destinationAccount, user, amount); 

जाहिर है "इस" प्रकार SecureBankAccount या कुछ और अधिक व्युत्पन्न की है। यह एक नए स्विसबैंक अकाउंट सहित अधिक व्युत्पन्न प्रकार का कोई भी मूल्य हो सकता है। SecureBankAccount स्विसबैंक अकाउंट के आविष्कारों के आसपास एक अंत-रन नहीं कर सका?

हाँ, बिल्कुल! और इसके कारण, स्विसबैंक अकाउंट के लेखक आवश्यक से समझते हैं कि उनकी बेस क्लास क्या करता है! आप बस कुछ कक्षाओं से निकलने वाले नहीं जा सकते हैं और सर्वश्रेष्ठ के लिए आशा करते हैं! आपके बेस क्लास के कार्यान्वयन को बेस क्लास द्वारा प्रकट संरक्षित तरीकों के सेट को कॉल करने की अनुमति है। यदि आप इससे प्राप्त करना चाहते हैं तो आपको उस वर्ग, या कोड के लिए प्रलेखन को पढ़ने की आवश्यकता है, और समझें कि आपकी संरक्षित विधियों को किस परिस्थिति में बुलाया जाएगा, और तदनुसार अपना कोड लिखें। व्युत्पन्न कार्यान्वयन विवरण साझा करने का एक तरीका है; यदि आप उस चीज़ के कार्यान्वयन विवरण को नहीं समझते हैं जो आप प्राप्त कर रहे हैं तो उससे प्राप्त न करें।

और इसके अलावा, बेस क्लास हमेशा व्युत्पन्न कक्षा से पहले लिखा जाता है। बेस क्लास ऊपर नहीं है और आप पर बदल रहा है, और संभवतः आप कक्षा के लेखक पर भरोसा करते हैं ताकि आप भविष्य के संस्करण के साथ चुपके से तोड़ने का प्रयास न करें। (बेशक, बेस क्लास में बदलाव हमेशा समस्याएं पैदा कर सकता है; यह भंगुर बेस क्लास समस्या का एक और संस्करण है।)

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

और इसके अलावा, हम हैं ताकि आप संभावित रूप से अधिक व्युत्पन्न कक्षाओं के रिसीवर पर संरक्षित तरीकों को कॉल कर सकें। मान लीजिए कि हमने इसे अनुमति नहीं दी और कुछ बेतुका कर दिया। किस परिस्थिति में संरक्षित विधि कभी कहलाया जा सकता है, अगर हम संभावित रूप से अधिक व्युत्पन्न कक्षाओं के रिसीवर पर संरक्षित विधियों को कॉल करने की अनुमति नहीं देते हैं? एकमात्र समय जब आप कभी भी उस दुनिया में संरक्षित विधि को कॉल कर सकते हैं, तो अगर आप अपनी खुद की संरक्षित विधि को एक सीलबंद कक्षा से बुला रहे थे! प्रभावी रूप से, संरक्षित तरीके लगभग कभी कहलाए जा सकते हैं, और जिसे कार्यान्वित किया गया था वह हमेशा सबसे व्युत्पन्न होगा। उस मामले में "संरक्षित" का क्या मतलब है? आपके "संरक्षित" का अर्थ "निजी" जैसा ही है, और इसे केवल एक सीलबंद वर्ग से ही बुलाया जा सकता है। इससे उन्हें कम उपयोगी बना दिया जाएगा।

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

क्या यह आपके प्रश्नों का उत्तर देता है?

+0

यह करता है, धन्यवाद। आप अपने बेस क्लास पर भरोसा कर सकते हैं लेकिन आप भाई कक्षाओं पर भरोसा नहीं कर सकते हैं, क्योंकि आप आधार चुनते हैं जबकि कोई भी भाई लिख सकता है। यह वास्तव में invariants के बारे में नहीं है, यह सुरक्षा के बारे में है। (एक बात जो मैं देखता हूं वह यह है कि "अच्छा" परिदृश्य में 'इस' पर संरक्षित विधि को कॉल करना शामिल है, और "बुराई" परिदृश्य में एक अन्य उदाहरण पर संरक्षित विधि को कॉल करना शामिल है - होस्टाइलबैंक अकाउंट कभी भी तत्काल नहीं होता है। क्या वहां * अच्छा "* परिदृश्य जिसमें' this' के अलावा अन्य उदाहरणों पर सुरक्षित विधियों को कॉल करना शामिल है?) –

+3

सबसे पहले, जैसे मैंने कहा, सुरक्षा के साथ सुलभता को स्वीकार करते समय सावधान रहें। अप्राप्य तरीके अभी भी पूरी तरह से भरोसेमंद कोड द्वारा कॉल करने योग्य हैं; पूरी तरह से भरोसेमंद कोड विधि तक पहुंचने तक मेटाडेटा को फिर से लिखता है। या, इसे देखने का एक और तरीका यह है कि "सुरक्षा" केवल एक विशेष प्रकार का आविष्कार है। असल में यह सुविधा * विश्वसनीय कोड * लिखने में सक्षम है। –

+0

दूसरा, निश्चित रूप से, ऐसे परिदृश्य हैं। उदाहरण के लिए कल्पना करें कि आपके पास एक संरक्षित विधि थी जो बाइनरी पेड़ को फिर से लिखने में सहायता करती थी। आपको संभवतः इसे अपने बाएं और दाएं उप पेड़ों पर कॉल करने में सक्षम होना चाहिए। एक लाल-काले पेड़ पुनर्लेखक केवल अन्य लाल-काले पेड़ उप-पेड़ों पर पुनर्लेखक को कॉल करने में सक्षम था। –

1

"संरक्षित" का अर्थ है कि एक सदस्य केवल परिभाषित वर्ग और सभी उप-वर्गों तक पहुंच योग्य है।

MySuperDerivedMyDerived का उप-वर्ग है, MemberMyDerived तक पहुंच योग्य है।इस बारे में सोचें: MySuperDerived एक MyDerived है और इसलिए इसके निजी और संरक्षित सदस्य (MyDerived से विरासत में) MyDerived तक पहुंच योग्य हैं।

हालांकि, YourDerivedMyDerived नहीं है और इसलिए इसके निजी और संरक्षित सदस्य MyDerived तक पहुंच योग्य नहीं हैं।

और तुम क्योंकि BaseBase का एक उदाहरण पर Member उपयोग नहीं कर सकते एक YourDerived जो एक MyDerived और न ही एक MyDerived के उपवर्ग नहीं है हो सकता है।

और एक्सेस चीज़ों को अनुमति देने के लिए स्थिर विधियों का उपयोग करके ऐसा न करें। यह encapsulation के उद्देश्य को हरा रहा है और एक बड़ी गंध है कि आपने चीजों को ठीक तरह से डिजाइन नहीं किया है।

+0

@ डाउनवॉटर: वास्तव में? आपका कारण क्या है? यह जवाब सहायक नहीं है? क्यूं कर? यह जवाब गलत है? कहा पे? – jason

+0

यहां 'परिभाषित वर्ग' बेस 'आधार' नहीं है? यही वह जगह है जहां 'सदस्य' परिभाषित किया गया है। –

+0

'बेस' से प्राप्त प्रत्येक वर्ग में' सदस्य 'नामक एक विधि भी है। यहां एक ठोस उदाहरण है। अगर मेरे पास 'स्पीक' और 'बिल्ली: बोलने वाला एनीमल' और 'कुत्ता: बोलना एनीमल' के साथ 'स्पीकिंग एनीमल' है तो वे अभी भी 'बोल सकते हैं'। यह सिर्फ इतना है कि जब तक वे 'स्पीक' ओवरराइड नहीं करते हैं, वे कार्यान्वयन के लिए अपने मूल वर्ग पर भरोसा करते हैं। यह बहुरूपता का मुद्दा है: यह कह रहा है कि एक वर्ग (एक व्युत्पन्न वर्ग) को किसी अन्य (बेस क्लास) के लिए प्रतिस्थापित किया जा सकता है। – jason

0

आप इस पूरी तरह गलत तरीके से सोच रहे हैं।

यह "कौन कॉल कर सकता है" के बारे में नहीं है, यह लगभग प्रतिस्थापन योग्य है जहां है।

माईडेरिव के उप-वर्गों को हमेशा माईडेरिव (उनके ओवरराइड संरक्षित तरीकों सहित) के लिए प्रतिस्थापन योग्य होना चाहिए। बेस के अन्य उप-वर्गों पर ऐसी कोई बाधा नहीं है, और इसलिए आप उन्हें MyDerived के स्थान पर प्रतिस्थापित नहीं कर सकते हैं।

+0

मैं समझता हूं कि MySuperDerived MyDerived के लिए प्रतिस्थापित किया जा सकता है। जो मुझे समझ में नहीं आता है, क्यों 'संरक्षित' का विनिर्देश MyDerived के तरीकों को उन सभी वर्गों पर सदस्य तक पहुंचने की अनुमति देता है जो MyDerived के लिए प्रतिस्थापन योग्य हैं, लेकिन कोई अन्य नहीं। मुझे नहीं पता कि डिजाइनरों ने क्या लक्ष्य सोचा था कि वे इसके साथ प्राप्त कर रहे थे। –

+0

आप) क्यों वर्ग ए * वर्ग बी के लिए substitutable नहीं * है, लेकिन नहीं तुम क्यों A.Method() फोन नहीं कर सकते हैं जैसे कि यह B.Method थे (? –

+0

मुझे समझ नहीं आता क्यों 'protected' संशोधक काम करने के लिए एक उपयोगी तरीका है" MyDerived केवल एक अभिव्यक्ति है जिसका प्रकार MyDerived के लिए substitutable है के माध्यम से संरक्षित तरीकों कॉल कर सकते हैं "है। मैं दृश्यता के आधार पर 'protected' की एक परिभाषा समझ सकते हैं (" बेस के संरक्षित सदस्य बेस के उपवर्गों में देखा जा सकता है, और अगर यह दिखाई दे रहा है तो आप इसे कॉल कर सकते हैं "), या वास्तविक क्रम प्रकार (" MyDerived में एक पद्धति पर आधारित केवल MyDerived "के उदाहरण पर संरक्षित सदस्यों को कॉल कर सकते हैं, लेकिन मुझे वास्तव में काम करने के तरीके के पीछे तर्क दिखाई नहीं देता है। –

0

http://msdn.microsoft.com/en-us/library/bcd5672a.aspx

एक आधार वर्ग का एक संरक्षित सदस्य एक व्युत्पन्न वर्ग केवल अगर पहुँच व्युत्पन्न वर्ग प्रकार के माध्यम से होता में पहुँचा जा सकता है।

"क्या?" का दस्तावेज़ीकरण है सवाल। अब मेरी इच्छा है कि मुझे पता था "क्यों?" :)

स्पष्ट रूप से virtual इस पहुंच प्रतिबंध के साथ कुछ लेना देना नहीं है।

हम्म, मुझे लगता है कि आप भाई बात के साथ कुछ करने के लिए पर हैं ... MyDerived कॉल करने के लिए YourDerived.Member

MyDerived Base.Member कॉल कर सकते हैं, तो यह वास्तव में पर काम कर रहा हो सकता है सक्षम नहीं होना चाहिए C# protected members accessed via base class variable

3

एरिक Lippert one of his blog posts में अच्छी तरह से यह स्पष्ट किया गया है: YourDerived का एक उदाहरण है और वास्तव में बुला रहा हो सकता है YourDerived.Member

आह, यहाँ एक ही सवाल है।

+0

मैंने उस पोस्ट को पढ़ लिया है और यह मेरे प्रश्न का उत्तर नहीं देता है। हालांकि, मुझे वहां एक टिप्पणी छोड़ने के लिए याद दिलाने के लिए धन्यवाद। –

+11

दोस्त, श्री लिपर्ट मेरे * पिता * हैं। –

+11

एरिक, दोस्त मेरा * बेटा * है। माफ़ कीजिये। –

1

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

छोटे-छोटे उपयोग किए गए protected internal शायद अधिकांश मामलों को कवर करेंगे जहां protected अकेले इसे काफी कट नहीं करता है।

+0

+1 वास्तव में "spec क्या कहता है" के बजाय "क्यों" को संबोधित करने के लिए +1 ... लेकिन इस प्रकार के उपयोग के लिए केवल एक अलग अलग त्रुटि संदेश/संख्या का अस्तित्व यह सुझाव देता है कि यह विशेष रूप से प्रतिबंधित है। –

+0

नहीं, इस प्रतिबंध के लिए अच्छे कारण हैं - जो, मुझे लगता है कि कई अन्य भाषाओं में सी ++ शामिल हैं। –

+0

पर्याप्त मेला, मैं डिजाइनरों में से एक के साथ बहस नहीं कर सकता। जैसा कि मैं हमेशा कहता हूं, यद्यपि: आप अपने दोस्तों को चुन सकते हैं, और आप अपनी नाक चुन सकते हैं, लेकिन आप अपने दोस्त की नाक नहीं चुन सकते हैं। इसके बारे में सोचो। – Aaronaught

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