2015-11-13 5 views
9

मैंने हाल ही में यूनिट-परीक्षण उद्देश्यों के लिए बेस क्लास पर एक इंटरफेस पेश किया और एक अजीब समस्या में भाग गया। यह कम से कम प्रतिलिपि प्रस्तुत करने योग्य परिदृश्य है:इंटरफ़ेस विरासत और संपत्ति छिपाने की समस्या

interface IBase 
{ 
    string Text { get; } 
} 

interface IChild : IBase 
{ 
} 

class Base : IBase 
{ 
    public string Text { get { return "Base"; }} 
} 

class Child : Base, IChild 
{ 
    public new string Text { get { return "Child"; }} 
} 

static void Main(string[] args) 
{ 
    var child = new Child(); 
    Console.WriteLine(child.Text); // Outputs "Child" 
    Console.WriteLine((child as Base).Text); // Outputs "Base" 
    Console.WriteLine(((child as Base) as IBase).Text); // Outputs "Child" 
} 

पहले दो Console.WriteLine आदेशों के उत्पादन में तार्किक है, लेकिन मैं पिछले एक के उत्पादन में स्वीकार करने के लिए असफल हो, तो यह और भी जब प्रकार Base की एक अस्थायी चर का उपयोग कर Child आउटपुट। क्या कोई यहां समझा सकता है कि क्या हो रहा है?

अद्यतन

इंटरफ़ेस IChild, ((child as Base) as IBase).Text अचानक "Base" में जो परिणाम को हटाकर। जो मुझे निष्कर्ष निकालता है कि, ChildIBase लागू करता है (सीधे या इंटरफ़ेस विरासत के माध्यम से) परिणाम "Child""Base" के बजाय होगा।

यह वास्तव में मुश्किल हो सकता है जब आप Base के बजाय IBase का तर्क लेने के लिए किसी अन्य वर्ग में किसी विधि को दोबारा प्रतिक्रिया देते हैं, क्योंकि अचानक यह अलग-अलग व्यवहार में होता है।

+4

आपको निश्चित रूप से इस गड़बड़ी से बचना चाहिए। 'नए' सदस्य की आवश्यकता कभी भी एक अच्छा संकेत नहीं है। –

+0

वास्तव में, 'नई' संपत्ति मृत कोड थी और अपवाद फेंक दिया। इसका कभी भी उपयोग नहीं किया गया था क्योंकि कोड हमेशा आधार प्रकार का उपयोग करता था। बेस इंटरफेस को जोड़कर उस मृत कोड को जीवन में लाया :) –

उत्तर

9

मूल रूप से आप यहाँ कास्ट कर रहे हैं:

(child as Base)Base करने के लिए और आप उपयोग कर रहे Base के Text क्षेत्र। यह स्पष्ट है।

लेकिन यहाँ में:

(child as Base) as IBase आप ChildBase के लिए और फिर IBase कास्ट कर रहे हैं जिसका मतलब है कि आप IBase को Child कास्ट कर रहे हैं, जिसका मतलब है Child के Text प्रदर्शित किया जाएगा। आप as का उपयोग कर अंतर्निहित वस्तु को नहीं बदल रहे हैं।

तो (child as Base) as IBase यहां child as IBase जैसा ही है।

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

संपादित सवाल तथ्य यह है कि यह जवाब सही है नहीं बदलता है। जैसा कि @InBetween ने कहा कि यह सिर्फ Text संपत्ति के कार्यान्वयन के तरीके को बदल रहा है। तो Child कक्षा अब IBase लागू नहीं करती है, इसलिए अब Base के Text का उपयोग सर्वोत्तम मिलान के रूप में किया जाएगा। असल में यह केवल प्रथम श्रेणी का उपयोग कर रहा है IBase

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