2009-10-09 19 views
11

कस्टम संग्रह बनाम जेनेरिक एक को उजागर करने के लिए सिफारिशें क्या हैं? , उदा,सार्वजनिक संग्रह के लिए कस्टम संग्रह बनाम जेनेरिक संग्रह

public class ImageCollection : Collection<Image> 
{ 
    ... 
} 

public class Product 
{ 
    public ImageCollection {get; set;} 
} 

वी.एस.

public class Product 
{ 
    public Collection<Image> Images{get; set;} 
} 

क्या मामलों आप एक कस्टम संग्रह बनाने पर विचार करेंगे? प्रत्येक विधि के पेशेवरों और विपक्ष क्या हैं?

+1

छवि की एक आईएलआईस्ट का खुलासा करने की एक तीसरी संभावना होगी। –

+0

जब मैं "संग्रह" कहता हूं तो मैं सामूहिक रूप से IList, List आदि का मतलब करता हूं। मुझे लगता है कि प्रश्न अभी भी लागू होता है भले ही इसकी सूची या IList आदि –

+0

.NET Fx दिशानिर्देश यह इंगित करने के लिए त्वरित हैं कि एक पठनीयता पहलू भी है, कई मामलों में एक सामान्य सूची पर कस्टम संग्रह का पक्ष लेना –

उत्तर

9

सामान्य तौर पर यह इंटरफेस में से एक, IEnumerable<T> जैसे, बेनकाब करने के लिए सबसे अच्छा है ICollection<T> या एक ठोस वर्ग के बजाय IList<T>

यह आपको अपने आंतरिक एपीआई को बदलने के मामले में अधिक लचीलापन प्रदान करता है। IEnumerable<T>, विशेष रूप से, आपको परिणामों की स्ट्रीमिंग की अनुमति देने के लिए बाद में अपने आंतरिक को संशोधित करने देता है, इसलिए सबसे लचीला है।

यदि आप अपने "संग्रह" के अपेक्षित उपयोग पैटर्न जानते हैं, तो आपको उचित एपीआई का खुलासा करना चाहिए जो भविष्य में कम से कम बाधाओं को प्रदान करता है। यदि, उदाहरण के लिए, आप जानते हैं कि लोगों को केवल अपने परिणामों को फिर से शुरू करने की आवश्यकता है, IEnumerable<T> का पर्दाफाश करें, ताकि आप बाद में किसी भी संग्रह में बदल सकें, या सीधे उपज रिटर्न का उपयोग करके स्विच कर सकें।

+0

मुझे लगता है कि मैं आंतरिक एपीआई के लिए सरल "संग्रह" का उपयोग करके आपसे सहमत हूं। लेकिन क्या आप अपने सार्वजनिक एपीआई में आईनेमेरेबल , आईसीओलेक्शन या IList का पर्दाफाश करेंगे? या आप एक कस्टम "संग्रह" तैयार करेंगे जो आईन्यूमेरेबल , आईसीओलेक्शन या IList लागू करता है, इस प्रकार ऊपर वर्णित पेशेवर गर्भ को कवर करता है? –

+4

नहीं। फ्रेमवर्क डिज़ाइन दिशानिर्देश पुस्तक वास्तव में (अब) सार्वजनिक एपीआई में आईन्यूमेरेबल , IList , आदि को उजागर करने का सुझाव देती है। वे आपको सार्वजनिक एपीआई तोड़ने के बिना अपने आंतरिक कार्यान्वयन को बदलने के लिए सबसे लचीलापन देते हैं। यदि आप कस्टम संग्रह को लागू करते हैं, तो आप हमेशा उस प्रकार तक लॉक हो जाते हैं, जब तक कि आप एपीआई संगतता को तोड़ना नहीं चाहते। –

5

मैं दूसरे के लिए जाऊंगा। क्लाइंट कोड को वैसे भी छवि प्रकार को जानना है।

पहला वाला केवल अधिक कोड का मतलब है।

1

Collection<T> का उपयोग करने का एकमात्र कारण यह है कि यदि आप वर्चुअल विधियों के सेट में हुक करना चाहते हैं जो आपको अंतर्निहित सूची में सभी उत्परिवर्तन देखने की अनुमति देता है। यह आपको हटाए गए कार्यों, घटनाओं को लागू करने आदि के जवाब देने के लिए अनुमति देता है ...

यदि आप इन संग्रह संशोधनों का जवाब देने या देखने में रुचि नहीं रखते हैं तो List<T> एक और उचित प्रकार है।

13

यदि आप एक सार्वजनिक एपीआई बना रहे हैं, तो निम्नलिखित फायदों के लिए कस्टम संग्रह का उपयोग करने पर विचार करें।

  • तानाना - आप एपीआई बदले बिना भविष्य में अपने कस्टम संग्रह करने के लिए सुविधाओं को जोड़ सकते।

  • पिछड़ा संगतता - आप संग्रह के खिलाफ प्रोग्राम किए गए मौजूदा कोड को तोड़ने के बिना, कृपया अपने संग्रह वर्ग के आंतरिक को बदलने के लिए स्वतंत्र हैं।

  • कम प्रभाव के साथ संभावित रूप से परिवर्तन तोड़ना आसान है। शायद बाद में आप तय करते हैं कि आप Collection<Image> नहीं बनना चाहते हैं, लेकिन एक अलग संग्रह प्रकार - आप अपने ImageCollection कक्षा को पहले के समान तरीके से प्राप्त कर सकते हैं, लेकिन कुछ अलग से प्राप्त होते हैं - और क्लाइंट कोड तोड़ने की संभावना नहीं होगी ।

यदि यह आंतरिक उपयोग कोड के लिए बस है, निर्णय जरूरी नहीं के रूप में महत्वपूर्ण है, और आप के साथ "सरल बेहतर है" जाने के लिए तय कर सकते हैं।

मेरे सिर के शीर्ष से एक उदाहरण ईएसआरआई से आर्कजीआईएस सर्वर एपीआई है - वे अपने एपीआई में कस्टम संग्रह का उपयोग करते हैं। हम इन कारणों से ज्यादातर हमारे एपीआई में कस्टम संग्रह का भी उपयोग करते हैं।

+1

दरअसल, किसी वर्ग के मूल प्रकार को बदलने में एक ब्रेकिंग परिवर्तन माना जाता है, (उदाहरण के लिए, यदि क्लाइंट कोड इसे 'संग्रह ' पर असाइन करता है) लेकिन आमतौर पर इससे कोई फर्क नहीं पड़ता। – SLaks

+0

मैं किसी भी आर्कजीआईएस एपीआई को "अच्छा" .NET का पालन करने के उदाहरण के रूप में कभी भी अनुशंसा नहीं करता। क्योंकि वे कॉम लपेटकर के साथ फंस रहे हैं उनमें विशिष्ट संग्रह का उपयोग - लेकिन वे भी नेट एपीआई में हर जगह जावा शैली iterators का उपयोग करें, IEnumerable या IEnumerable जहां वे चाहिए, और कई अन्य htings कि जीवन बहुत कठिन बना संपर्क में न आएं। –

+0

@ स्लक्स - बहुत सच है। यह वैसे भी इसे कम करता है। – womp

5

मुख्य कारण यह है कि मैं सोच सकता हूं कि आप उस संग्रह पर चलने वाली छवियों के संग्रह के लिए विशिष्ट कुछ विधियां चाहते हैं। फिर मैं उन विधियों को रखने के लिए एक छवि चयन वर्ग का उपयोग करूंगा। क्लासिक encapsulation।

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

class Product { 
    private readonly Collection<Image> _images; 
    public Product() { _images = new Collection<Image>(); } 
    public Collection<Image> Images { get { return _images; } } 
} 

-Oisin

+2

+1। –

1

मैं आंतरिक रूप से एक्स्टेंसिबल बनाने के लिए सार्वजनिक जेनेरिक संपत्ति रखना पसंद करता हूं, लेकिन एक निजी क्षेत्र वास्तविक कार्यक्षमता वाला कस्टम होगा।

यह आमतौर पर इस तरह दिखता है:

public interface IProduct 
{ 
    ICollection<Image> Images { get; } 
} 

public class Product : IProduct 
{ 
    private class ImageCollection : Collection<Image> 
    { 
     // override InsertItem, RemoveItem, etc. 
    } 

    private readonly ImageCollection _images; 
    public ICollection<Image> Images 
    { 
     get { return _images; } 
    } 
} 

मैं भी अक्सर कस्टम संग्रह वर्ग एक अलग वर्ग है, जो मुझे/जोड़ने के दौरान माता-पिता वर्ग के कुछ निजी सदस्यों को संशोधित दूर करने के लिए अनुमति देता है के अंदर नेस्टेड हैं।

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