2012-02-20 10 views
5

क्यों है यह है कि निम्न कानूनी सी # है:इंटरफेस करने संपत्ति की अनुमति दी है, लेकिन सार संपत्ति के लिए नहीं एक्सेसर जोड़ना

public interface ISomeInterface 
{ 
    int SomeProperty 
    { 
     get; 
    } 
} 

public class SomeClassImplementingInterface : ISomeInterface 
{ 
    public int SomeProperty 
    { 
     get { return 32; } 
     protected set {} 
    } 
} 

लेकिन यह नहीं है:

public abstract class SomeAbstractClass 
{ 
    public abstract int SomeProperty 
    { 
     get; 
    } 
} 

public class SomeClassExtendingAbstractClass : SomeAbstractClass 
{ 
    public override int SomeProperty 
    { 
     get { return 32; } 
     protected set {} 
    } 
} 

निम्नलिखित में बाद परिणाम संकलन-समय त्रुटि:

'InterfaceAbstractTest.SomeClassExtendingAbstractClass.SomeProperty.set': cannot override because 'InterfaceAbstractTest.SomeAbstractClass.SomeProperty' does not have an overridable set accessor InterfaceAbstractTest

पूर्व की अनुमति देने के दौरान उत्तरार्द्ध को अस्वीकार करने का तर्क क्या है?

+0

मुझे लगता है कि वे यहाँ शब्द "ओवरराइड" है। ओवरराइड करने के लिए कोई सेट विधि नहीं है। –

+0

या यह है कि ओवरराइड कीवर्ड को एक्सेसर स्तर के बजाय संपत्ति स्तर पर निर्दिष्ट किया गया है? आखिरकार, प्रत्येक एक्सेसर एक अलग विधि है जब यह नीचे आता है। –

+1

दायां - अमूर्त कीवर्ड संपत्ति स्तर पर काम करता है, न कि एक्सेसर स्तर। –

उत्तर

3

क्योंकि इंटरफ़ेस का उपयोग कर एक फोन करने वाले केवल परवाह करता है कि इंटरफेस कम से कम के implementer इंटरफेस की परिभाषा को लागू करता है, @davisoa राज्यों के रूप में है, जबकि अपने उदाहरण में SomeAbstractClass एक सार्वजनिक अनुबंध जिसमें कहा गया है परिभाषित करता है वास्तव में प्रकार, पहुंच, और (गुणों के लिए) सदस्यों की पठनीयता/उत्तरदायित्व।

यदि आप SomeProperty (या तो आधार या बाल वर्ग से) के PropertyInfo प्राप्त करने के लिए प्रतिबिंब का उपयोग करते हैं, तो उसे उस जानकारी को कहीं से हल करने की आवश्यकता है। पठनीयता/उत्तरदायित्व को बदलने के लिए बाल वर्ग को अनुमति देना रिटर्न प्रकार या तर्क सूची में परिवर्तन के रूप में अनुबंध उल्लंघन का उतना ही होगा।

उदाहरण के लिए कल्पना कीजिए:

SomeAbstractClass sc = new SomeClassExtendingAbstractClass(); 
PropertyInfo pi = sc.GetType().GetProperty("SomeProperty"); 
Console.Out.WriteLine(pi.CanWrite); // What should be printed here? 
2

ऐसा इसलिए है क्योंकि इंटरफेस कार्यान्वयन एक वादा कर रहा है कि एक संपत्ति SomeProperty होगी जिसे आप "प्राप्त" कर सकते हैं।

अमूर्त वर्ग कार्यान्वयन एक वादा कर रहा है कि यह बाल वर्ग एक सार्वजनिक विधि के साथ SomeProperty संपत्ति का कार्यान्वयन प्रदान करेगा।

अंत में, आधार वर्ग कुछ है कि अधिरोहित, जबकि इंटरफेस एक अनुबंध को परिभाषित कर रहा है होना चाहिए परिभाषित करने है।

+0

जहां तक ​​मेरा संबंध है, 'SomeClassExtendingAbstractClass' * * सार्वजनिक प्राप्त विधि के साथ एक संपत्ति' SomeProperty' प्रदान करता है। अमूर्त इंटरफेस के खिलाफ काम करने वाले किसी के लिए यह अपरिहार्य है कि एक सेटटर भी है। इसलिए, मेरा सवाल है। कल्पना करें कि प्रत्येक प्राप्त/सेट के बजाय विधियां थीं। कल्पना करें कि 'SetValue' विधि प्रदान करने में सक्षम नहीं है क्योंकि आपने एक अमूर्त वर्ग बढ़ाया है जिसमें' GetValue' विधि है। –

+2

@KentBoogaart यह बात है- वे सिर्फ गेटर्स और सेटर्स नहीं हैं। गुण .NET में प्रथम श्रेणी के नागरिक हैं, और संपत्ति से जुड़े उनकी पठनीयता/उत्तरदायित्व के बारे में अनुबंध मेटाडेटा है। –

1

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

0

क्या जरूरी है कि दोनों मौजूदा संपत्ति को ओवरराइड और एक नया के साथ यह शैडो एक पढ़ने-लिखने के लिए है। दुर्भाग्यवश, .NET एक वर्ग के भीतर किसी सदस्य को ओवरराइड करने और छायांकन करने का कोई माध्यम प्रदान नहीं करता है। सबसे अच्छा एक ऐसा कर सकता है शायद अमूर्त बेस क्लास एक ठोस गैर वर्चुअल रीड-ओनली प्रॉपर्टी को परिभाषित करे, जिसका गेटटर एक अमूर्त फ़ंक्शन कहता है। एक व्युत्पन्न वर्ग तब संपत्ति को गैर-वर्चुअल रीड-राइट फ़ंक्शन के साथ छाया कर सकता है जो उसके गेटर में एक ही फ़ंक्शन को कॉल करता है, और इसके सेटर में एक नया सार या वर्चुअल फ़ंक्शन।

1

यह डिज़ाइन द्वारा है। मैं सी # भाषा चश्मा से उद्धृत कर रहा हूँ: क्योंकि इंटरफेस अधिक लचीलेपन सार वर्गों की तुलना में ठेके के प्रकार के होते हैं

An overriding property declaration must specify the exact same accessibility modifiers, types and name as the inherited property, if the inherited property has only a single accessor (i.e.,... ready only or write-only), the overriding property must include only that accessor.

कि decesion के पीछे का कारण हो सकता है। इंटरफेस पूरे कार्यान्वयन के बजाए केवल कम से कम आम denominator की परवाह करता है। मुझे लगता है कि दूसरे पर एक डिजाइन चुनने के अच्छे कारण हैं।