2011-09-21 10 views
17

मैं एक आधार वर्ग एक आभासी संपत्ति है कि है:संपत्ति सेटटर की अनुमति नहीं होने पर फेंकने का क्या अपवाद है?

public virtual string Name { get; set; } 

तो मैं एक व्युत्पन्न वर्ग है कि केवल संपत्ति

public override string Name 
{ 
    get { return "Fixed Name"; } 
} 

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

तो मैंने सोचा कि मैं कुछ ऐसा करना चाहते हैं:

public override string Name 
{ 
    get { return "Fixed Name"; } 
    set { throw new Exception(); } //which exception type? 
} 

तो दो (संबंधित प्रश्नों):

  1. वहाँ एक बेहतर पैटर्न मुझे इस्तेमाल करने के लिए है?
  2. यदि मुझे उपरोक्त पैटर्न का उपयोग करना चाहिए, तो उपयोग करने के लिए क्या अपवाद है?

संपादित: कुछ वजहों एक अपवाद से अधिक प्राथमिकता दी जाएगी एक और अच्छा होगा। मेरे सहकर्मी और मेरे पास NotSupported और InvalidOperation के बीच एक ही तर्क था।

+2

क्या कोई कारण है कि आपको बेस क्लास में सेटर की आवश्यकता क्यों है? –

+0

@DarylTeo हां, बेस क्लास को मैन्युअल रूप से नाम सेट करने का समर्थन करने की आवश्यकता है, हालांकि यह कन्स्ट्रक्टर में हो सकता है। – Ray

उत्तर

24

NotSupportedException अपवाद फेंको। लिंक से उद्धरण:

वहाँ तरीकों कि आधार वर्ग में समर्थित नहीं हैं, उम्मीद है कि इन तरीकों व्युत्पन्न कक्षाओं में बजाय लागू किया जाएगा के साथ कर रहे हैं। व्युत्पन्न वर्ग बेस क्लास के तरीकों के के केवल एक उप-समूह को लागू कर सकता है, और असमर्थित विधियों के के लिए NotSupportedException फेंक सकता है।

मेरी राय यह है कि InvalidOperationException एक सही विकल्प नहीं है। MSDN से उद्धरण:

अपवाद है जब एक विधि कॉल वस्तु की वर्तमान स्थिति के लिए अमान्य है कि फेंक दिया है।

आपकी स्थिति में वर्तमान स्थिति के बारे में कुछ भी नहीं है। यह है कि कक्षा अनुबंध ऑपरेशन का समर्थन नहीं करता है।

+0

एचएम .. वह उद्धरण समझ में आता है, हालांकि यह मेरे विपरीत काम के विपरीत है। – Ray

+0

+1 उद्धरण प्रश्न का सटीक उत्तर है और यह है कि जब मैं कक्षाएं प्राप्त कर लेता हूं तो मैं इसे कैसे कर रहा हूं जो कुछ कारणों से एक अमूर्त विधि लागू नहीं कर सकता –

+0

@ रे - आप बिल्कुल वही कर रहे हैं। इसे फिर से पढ़ें :) –

-3

यहां मैं NotImplementedException के लिए जाऊंगा।

+10

-1 यह संकेत है कि यह ** अभी तक ** लागू नहीं है, लेकिन यह जा रहा है। ज्यादातर बार, यह उत्पादन –

+0

मेला बिंदु में उपयुक्त नहीं है। अक्सर कोड जेनरेटर के लिए डिफ़ॉल्ट अपवाद के रूप में उपयोग किया जाता है। – Carra

7

यह लिस्कोव प्रतिस्थापन सिद्धांत को तोड़ता है और यही कारण है कि यह बुरा विचार है।

4

यदि आप बेस क्लास के निर्माता को सेटटर को स्थानांतरित करने और सेटटर को निजी बनाने की कोशिश कर सकते हैं। या जैसा कि जॉन ने उन सभी गेटर्स के साथ अमूर्त बेस क्लास/इंटरफ़ेस बनाने का सुझाव दिया जो सभी कार्यान्वयन में समर्थित हैं।

यह अपवाद फेंकने के साथ पूरी स्थिति से बच जाएगा।

1

यदि बेस क्लास वास्तव में नाम सेट करने की अनुमति देता है (एक अमूर्त सेटटर को उजागर करने के विपरीत जो काम करने की गारंटी नहीं है), व्युत्पन्न कक्षाओं को भी ऐसा करना चाहिए।यदि आप एक पदानुक्रम चाहते हैं जिसमें कुछ वर्ग शामिल हैं जहां नाम सेट किया जा सकता है और जहां कुछ नहीं हो सकता है, तो दोनों प्रकार की कक्षा को एक गैर-वर्चुअल रीड-राइट Name संपत्ति के साथ एक सार ReadableXX कक्षा से उत्तराधिकारी होना चाहिए, जो GetName और SetName विधियों को सारणी देता है । यह इंगित करने के कुछ साधन भी प्रदान करना चाहिए कि SetName समर्थित होगा (उदा। CanSetName विधि)। कक्षा का एकमात्र संस्करण केवल "नई" पढ़ने-योग्य Name संपत्ति को परिभाषित कर सकता है जो GetName पर श्रृंखला करेगा, और SetNameNotSupportedException फेंक ओवरराइड करें। यदि कक्षा के लिए विनिर्देश कहता है कि SetName केवल तभी काम करेगा यदि CanSetName सत्य लौटाता है, तो SetName कक्षाओं में अपवाद फेंकते हैं जहां CanSetName रिटर्न झूठी लिस्कोव प्रतिस्थापन सिद्धांत का उल्लंघन नहीं करेगा।

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