2010-12-15 4 views
5

में कंक्रीट सेटर के साथ सार गेटर मैं केवल पढ़ने के लिए संग्रह के लिए एक सार आधार वर्ग लिखने की कोशिश कर रहा हूं जो IList लागू करता है। इस तरह के बेस क्लास को NotSupportedException फेंकने के लिए सेट-इंडेक्सर को कार्यान्वित करना चाहिए, लेकिन गेट-इंडेक्सर को सार के रूप में छोड़ दें। क्या सी # ऐसी स्थिति की अनुमति देता है? यहाँ मैं अब तक है:सी #

public abstract class ReadOnlyList : IList { 

    public bool IsReadOnly { get { return true; } } 

    public object this[int index] { 
     get { 
      // there is nothing to put here! Ideally it would be left abstract. 
      throw new NotImplementedException(); 
     } 
     set { 
      throw new NotSupportedException("The collection is read-only."); 
     } 
    } 

    // other members of IList ... 
} 

आदर्श रूप में ReadOnlyList सेटर को लागू लेकिन गेटर सार छोड़ने के लिए सक्षम होगा। क्या कोई वाक्यविन्यास है जो इसकी अनुमति देता है?

+5

मामले में यह सिर्फ एक अभ्यास नहीं है, आप ढांचे –

+0

धन्यवाद में ReadOnlyCollection है; मैं आमतौर पर ReadOnlyCollection का उपयोग करता हूं, हालांकि इस विशिष्ट मामले को IList के कस्टम कार्यान्वयन के लिए बुलाया गया है। मैं अपने परिदृश्य को एक प्रश्न पूछने के लिए आवश्यक न्यूनतम तक सरल बनाना चाहता हूं। –

उत्तर

8

प्रतिनिधि संरक्षित सदस्यों जिसे फिर आप के रूप में सार या आभासी वांछित व्यवहार के आधार पर चिह्नित कर सकते हैं करने के लिए काम की आवश्यकता नहीं है। कुछ इस तरह का प्रयास करें:

// implementor MUST override 
protected abstract object IndexerGet(int index); 

// implementor can override if he wants.. 
protected virtual void IndexerSet(int index, object value) 
{ 
    throw new NotSupportedException("The collection is read-only."); 
} 

public object this[int index] { 
    get { 
    return IndexerGet(index); 
    } 
    set { 
    IndexerSet(index, value); 
    } 
} 
+0

इंडेक्सरसेट * शायद * आभासी नहीं होना चाहिए - वास्तव में, बस सेटर में 'NotSupportedException' फेंकना ठीक है। –

+1

धन्यवाद m0sa। मैंने इसे उत्तर के रूप में स्वीकार कर लिया है क्योंकि यह सेटटर को लागू करने और प्राप्तकर्ता को लागू करने के लिए व्युत्पन्न कक्षाओं को मजबूर करने के लक्ष्य को प्राप्त करने का एकमात्र उत्तर है। उल्लेख नहीं है कि यह अब तक का एकमात्र उत्तर है जो संकलित होगा! –

-1

आप सेटटर क्यों चाहते हैं - सेटटर की अनुपस्थिति इसकी केवल पढ़ने वाली संपत्ति को इंगित करेगी।

संपादित करें: jgauffin ने इंगित किया कि सेटर आईएलआईस्ट से आता है। तो आपके पास दो विकल्प हो सकते हैं:

  1. व्यक्तिगत रूप से आईएलआईस्ट लागू करें और इंडेक्सर के लिए सार्वजनिक सार प्राप्तकर्ता प्रदान करें (हालांकि 100% निश्चित नहीं है कि मेरे पास दो इंडेक्सर्स हो सकते हैं)।
  2. इंडेक्सेटर गेटर एक अमूर्त विधि जैसे GetItem का आह्वान करेगा।
+0

क्योंकि 'IList' सूचकांक को परिभाषित करता है। – jgauffin

+0

इंटरफ़ेस द्वारा यह [आवश्यक] (http://msdn.microsoft.com/en-us/library/system.collections.ilist.item.aspx) है। –

0

आप सेटटर को निजी क्यों नहीं बनाते?

public abstract class ReadOnlyList : IList 
    { 

     public bool IsReadOnly { get { return true; } } 

     public object this[int index] 
     { 
      get 
      { 
       // there is nothing to put here! Ideally it would be left abstract. 
       throw new NotImplementedException(); 
      } 
      private set 
      { 
       // your private implementation 
      } 
     } 

     // other members of IList ... 
    } 
+4

इंडेक्सर को 'IList' – jgauffin

+2

में परिभाषित करने के बाद त्रुटि संकलित करें इंटरफ़ेस द्वारा सार्वजनिक होने की आवश्यकता है, और आपने गेटर सार को रखने की इच्छा को संबोधित नहीं किया है। –

+1

मिमी सही, उस बारे में नहीं सोचा था –

2

नहीं, आपके पास सदस्य सार के साथ कोई संपत्ति नहीं हो सकती है और अन्य लागू किया जा सकता है। मैं क्या करूँगा पूरी संपत्ति को सार के रूप में सेट करना और विरासतकर्ताओं को जो कुछ भी आप चाहते हैं उसे फिर से परिभाषित करना है।

+0

धन्यवाद SoMoS; हालांकि मैंने एमएएसए के जवाब को स्वीकार किया जिसने प्रश्न का उत्तर दिया, मैं अंततः आपके द्वारा सुझाए गए दृष्टिकोण के साथ चला गया, ताकि अतिरिक्त स्तर पर संकेत मिले। –

+0

कोई समस्या नहीं आदमी, वैसे भी मोसा जवाब भी एक अच्छा है। –

0

नहीं। और यदि आप इसे करने का कोई तरीका ढूंढेंगे तो यह वास्तव में लिस्कोव प्रतिस्थापन सिद्धांत को तोड़ देगा।

LSP यहाँ के बारे में और अधिक पढ़ें: Can you explain Liskov Substitution Principle with a good C# example?

+0

यह एलएसपी कैसे तोड़ता है?कंक्रीट सबक्लास को ठोस गटर कार्यान्वयन प्रदान करना होगा। यदि ऐसा होता है, तो उस सबक्लास को (अन्य मुद्दों को अनुपस्थित करना चाहिए) एक अच्छी तरह से व्यवहार किया जाना चाहिए 'IList' (जो [अनुमति] हैं (http://msdn.microsoft.com/en-us/library/system.collections.ilist। isreadonly.aspx) केवल पढ़ने के लिए)। –

+1

क्योंकि 'IList' का उपयोग करने वाले किसी भी व्यक्ति को सूची में आइटम प्राप्त करने और सेट करने में सक्षम होने की उम्मीद है। नेट फ्रेमवर्क में 'ReadOnlyCollection' भी एलएसपी का उल्लंघन करता है क्योंकि यह उस आवश्यकता को पूरा नहीं करता है। – jgauffin

+0

नहीं। यदि आपने मेरा लिंक चेक किया है, तो आप देखेंगे कि 'IList' स्पष्ट रूप से केवल पढ़ने-योग्य होने के लिए डिज़ाइन किया गया था; यही कारण है कि 'IList.IsReadOnly' propery है। इस प्रकार, केवल पढ़ने के लिए उपclass आसानी से "विकल्प" कर सकते हैं। –

0

आप इसे फिर एक केवल पढ़ने के लिए संग्रह होना चाहते हैं क्यों IList लागू?

आपको इसके बजाय IEnumerable लागू करना चाहिए।

+1

फेंकता है स्पष्ट रूप से [अनुमति] है (http: // msdn .microsoft.com/en-us/लाइब्रेरी/system.collections.ilist.isreadonly.aspx) केवल पढ़ने के लिए। 'IENumerable' यादृच्छिक पहुंच प्रदान नहीं करता है। –

+0

हालांकि यह लगभग पूरी तरह से 'ReadOnlyCollection <>' समाधान के रूप में नहीं दिखाया गया है, प्रैक्टिस में यह अक्सर पर्याप्त होता है और इसमें एक सरल एपीआई होने का गुण भी होता है - और यही मायने रखता है, है ना? मैं केवल ReadOnlyCollection की वकालत करता हूं जहां IENumerable अपर्याप्त है। –

+0

इसके अलावा, 'आईनेमेरेबल' प्लेयर टाइप सिस्टम के साथ अच्छे हैं: मैं आम तौर पर संग्रहों को घुमाने और क्रमबद्ध करने के तरीकों का उपयोग करता हूं - और ये काम ILists पर। केवल-पढ़ने वाले कलाकार रन-टाइम पर असफल हो जाएंगे, जबकि एक आईनेमरेबल पास करने से संकलन समय में असफल हो जाएगा; यह अच्छा व्यवहार है। –

-2

आप एक सेटर

public abstract object this[int index] { get; } 
+0

वही बात कहने वाले अन्य उत्तरों को पढ़ें। –