2015-09-29 11 views
5

मुझे कुछ अजीब पता चला, जिसे मैंने काम करने की उम्मीद नहीं की थी, वास्तव में काम करता है। बल्कि क्षेत्र सेबेस क्लास से सबक्लास 'संपत्ति एक्सेस करें

public abstract class Parent { 

    public Parent() { 
    var constName = ConstName;   // <-- surprisingly, this works 
    var randomName = RandomName;   // <-- surprisingly, this works 
    } 

    public abstract string ConstName { get; } 

    public abstract string RandomName { get; } 

} 


public class Child : Parent { 

    public override string ConstName { get { return "Mike"; } } 

    public override string RandomName { get { return new Random().Next().ToString(); } } 

} 

Name एक गैर स्थिर संपत्ति है: मैं निर्माता 'आधार वर्ग से (स्थिर) संपत्ति' एक उपवर्ग पहुँच सकते हैं। मैंने हमेशा सोचा कि एक प्रकार के प्रारंभिक (static और const फ़ील्ड के लिए) निष्पादित किए गए थे, फिर उसके बेस क्लास के, फिर बेस सीटीओ और फिर सबक्लास 'सीटीओआर। जिसका मतलब है कि बच्चे अभी तक पूरी तरह से निर्मित नहीं है जबकि माता-पिता ctor में।

क्या यह "कानूनी" सी # है जो सभी परिस्थितियों में काम करेगा? यह क्यों काम करता है?

संपादित करें:

नहीं, यह एक डुप्लिकेट प्रश्न नहीं है। उसमें मेरे प्रश्न में कक्षा स्कीमा नहीं है।

+0

आपके पास माता-पिता के अंदर नाम संपत्ति है! तो तकनीकी रूप से यह कानूनी और सही है। –

+0

@ निकिता हाँ, लेकिन अभी तक बच्चा नहीं बनाया गया है। मेरे प्रश्न में प्रारंभिकरण के आदेश को पढ़ें। –

+0

तो आप कह रहे हैं कि जब आप डीबग करते हैं और यह आधार निर्माण के लिए जाता है, तो आपको नाम माइक के रूप में मिला है ?? –

उत्तर

3

आप उपप्रकारों के सार/आभासी सदस्यों तक पहुंच सकते हैं। संपत्ति गेटर्स अंत में विधियां हैं।

लेकिन।

जैसा कि आपने कहा था, उप-वर्ग कन्स्ट्रक्टर अभी तक निष्पादित नहीं किया गया था। इसलिए, इसका दुष्प्रभाव हो सकता है। यही कारण है कि आप FxCop से एक चेतावनी प्राप्त करते हैं।

public abstract class Parent 
{ 
    public Parent() 
    { 
    // NullReferenceException here: 
    var nameLength = Name.Length; 
    } 

    public abstract string Name { get; } 

} 

public class Child : Parent 
{ 
    private string name; 

    public Child() 
    { 
    name = "My Name"; 
    } 

    public override string Name { get { return name; } } 
} 

भी बदतर:

public class Child : Parent 
{ 
    private string name; 

    public Child() 
    { 
    name = "My Name"; 
    } 

    public override string Name 
    { 
    get 
    { 
     // NullReferenceException here. 
     // You didn't expect that this code is executed before 
     // the constructor was, did you? 
     return name.Substring(0, name.Length - 1); 
    } 
    } 
} 

इसलिए यह करने के लिए अनुशंसित नहीं है।

+0

सही। तो मैं इस व्यवहार से आश्चर्यचकित होना सही था, क्योंकि यह समझ में नहीं आता है। मुझे लगता है कि इस व्यवहार को रोकने के लिए आसान नहीं था, इसलिए कंपाइलर टीम ने इसे अनुमति दी, लेकिन आपको यह बताने के लिए FxCop चेतावनी बनाई कि यह एक "बहुत बुरा विचार" है। असल में, यह नॉन-निर्धारिती आउटपुट में परिणाम देता है! –

+0

शानदार संपादन! पूरी तरह से समस्या बताता है! +1 –

+0

मुझे लगता है कि मेरा प्रश्न इस तरह से सोचा जा सकता है: सिर्फ इसलिए कि कुछ संकलित करता है, यह "सही" नहीं बनाता है। विचित्र किनारे के मामले हैं जो संकलक आपको सिखा नहीं सकते हैं। रचनाकारों के अंदर बहुत गहरा जादू है :)। –

4

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

ध्यान दें कि मैं कहता हूं: उदाहरण नहीं बनाया जा सकता है। यदि कोई सबक्लास संपत्ति नाम लागू नहीं करता है, तो वर्ग मौजूद हो सकता है, लेकिन आप इसे तुरंत चालू नहीं कर सकते हैं।

कक्षा अभिभावक संपत्ति का नाम लागू नहीं करता है, इसलिए आप माता-पिता को तत्काल नहीं कर सकते हैं।

कक्षा बच्चा हालांकि नाम लागू करता है, इसलिए आप इसे तुरंत चालू कर सकते हैं, और क्योंकि आपने वादा किया था कि कक्षा के प्रत्येक ऑब्जेक्ट (= तत्काल) में संपत्ति का नाम है, आप यह सुनिश्चित कर सकते हैं कि हालांकि आप सभी जानते हैं कि यह एक अभिभावक है , आप यह भी जानते हैं कि इसका नाम है।

यह subtyping Wikipedia about polymorphism

यह मुख्य कारण है कि आप उपवर्ग चाहेगा हो सकता है में बहुरूपता का बुनियादी सिद्धांत है।

+0

हां यह समझ में आता है। आप संकलन-समय अनुबंध का जिक्र कर रहे हैं, इसलिए आप बच्चे की संपत्ति के अस्तित्व के बारे में सुनिश्चित हो सकते हैं। लेकिन यहां बिंदु यह है कि आप बच्चे (पूरी तरह से) निर्माण से पहले यह कर रहे हैं। मैं यही समझ में नहीं आता? –

+0

एक दूसरे पढ़ने पर, आपका जवाब मूल रूप से बहुरूपता के समग्र विचार (बहुत अच्छी तरह से) बताता है। लेकिन निर्माण का आदेश नहीं, जो इस प्रश्न के केंद्र में है। –

+1

अमूर्त कार्य के कारण, माता-पिता के निर्माता को पता है कि जिस वस्तु का निर्माण किया जाना है वह माता-पिता का उप-वर्ग है। हालांकि उपclass का निर्माण अभी तक समाप्त नहीं हुआ है, subclass पहले से ही पूरी तरह से मौजूद है। प्रत्येक कन्स्ट्रक्टर में, भले ही कोई बेस क्लास न हो, आपको उस ऑर्डर के बारे में सावधान रहना होगा जिसमें आप ऑब्जेक्ट के आइटम को प्रारंभ करते हैं। आप विधियों और गुणों को कॉल कर सकते हैं, लेकिन यह सुनिश्चित कर लें कि वे केवल उन वस्तुओं का उपयोग करें जो पहले ही प्रारंभ हो चुके हैं। –

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