2011-07-07 12 views
8

मेरे पास List<Location> का उप-वर्ग है जिसे LocationList कहा जाता है। यह हमारे लिए अन्य गुणों को जोड़ने का एक सुविधाजनक तरीका है (जैसे IsExpanded और इस तरह हम यूआई में उपयोग कर सकते हैं। काफी अच्छा है। लेकिन अब, हम चाहते हैं कि प्रत्येक स्थान अपने माता-पिता से अवगत रहें। ऐसे में, हमें अधिसूचित होने की आवश्यकता है हम ObservableCollection उपयोग कर सकते हैं कुछ LocationList में जोड़ा जाता है, लेकिन आप Add और Remove करती है।, कि एक दृश्य/ViewModel के और अधिक का निर्माण है। यह शुद्ध मॉडल डेटा है।मैं सी # 4.0 में एक सामान्य सूची में जोड़ों का पता कैसे लगा सकता हूं?

ज़रूर हम स्वयं को जोड़ते समय माता पिता सेट कर सकते हैं यह संग्रह में है, लेकिन मुझे गैर-स्वचालित तर्क से नफरत है क्योंकि इसके सेट को सही ढंग से लागू करने के लिए कुछ भी नहीं है। संग्रह (अच्छी तरह से, सूची) स्वचालित रूप से कहें 'अरे ... आपको जोड़ा जा रहा है, इसलिए मैं आपका सेट करूंगा कक्षा के अभिभावक जो मेरे मालिक हैं। "मैं जो हूं उसके बाद हूं।

मेरा विचार उप-वर्ग List<Location> के बजाय है, इसके बजाय केवल एक सीधी कक्षा बनाएं जो आंतरिक रूप से List<Location> का उपयोग करती है, और फिर मैं बस अपने स्वयं के जोड़ें/निकालें विधियों का पर्दाफाश कर सकता हूं और समायोजन को 'माता-पिता' में संभाल सकता हूं। हालांकि, आंतरिक संग्रह पर गणना करने में सक्षम होने के कारण इतने ब्रेक कर रहे हैं क्योंकि यह अंदर है।

उस ने कहा, क्या List<Location> में परिवर्तनों को सुनने के लिए कोई तरीका है या कम से कम अपने IEnumerable इंटरफ़ेस को लपेटा हुआ ऑब्जेक्ट से इसके रैपर में सौंपना है?

उत्तर

8

इसके स्थानसूची को Collection<Location> से प्राप्त करने के लिए बदलें। मुझे नहीं पता कि क्यों List<T> सील नहीं किया गया है, लेकिन यह विस्तार योग्य नहीं है।

स्रोत: फ्रेमवर्क डिजाइन दिशानिर्देश, द्वितीय संस्करण, पृष्ठ 251:

List<T> एपीआई और लचीलेपन की पवित्रता की कीमत पर प्रदर्शन और शक्ति के लिए अनुकूलित है।

+0

यह लागू करने के लिए सबसे आसान लगता है ... संग्रह संग्रह में बदल रहा है जो ऑब्जर्जेबल कोलेक्शन के सभी ओवरहेड को जोड़ता नहीं है, हालांकि आप सूची की तुलना में थोड़ा प्रदर्शन खो देते हैं। फिर भी, यह काफी अच्छा है इसलिए आपको वोट मिल रहा है। धन्यवाद! – MarqueIV

4

List<T> सदस्यों को InsertItem<T>, RemoveItem<T> आदि संरक्षित किया गया है ताकि आप जो भी चाहते हैं उसे करने के लिए अपने व्युत्पन्न वर्ग में ओवरराइड कर सकें।

** अद्यतन **

वास्तव में ऊपर है गलत है, यह Collection<T> इन संरक्षित तरीकों है कि है। आम तौर पर, कस्टम लिस्ट क्लास प्राप्त करते समय, Collection<T> से List<T> के बजाय प्राप्त करने की अनुशंसा की जाती है।

this answer देखें।

+1

यदि आप InsertItem/RemoveItem को ओवरराइड करने जा रहे हैं, तो आप केवल एक संस्करण का उपयोग क्यों नहीं करते हैं जहां कार्य पहले से ही किया गया है (ObservableCollection) –

+0

ऑब्जर्जेबल कोलेक्शन वास्तव में मॉडल की तुलना में व्यूमोडेल के लिए अधिक अनुकूलित है। परिवर्तन के बारे में जागरूक होने वाले एकमात्र व्यक्ति को स्वयं संग्रह होता है। आपको पूर्ण परिवर्तन-सूचना ओवरहेड की आवश्यकता नहीं है। – MarqueIV

+1

@ मार्कीव: "मैं एक और ग्यारह मिनट के लिए भी आपका जवाब स्वीकार नहीं कर सकता" - साथ ही शुरुआती उत्तर गलत था - निशान से बहुत जल्दी। अपडेट देखें और माइकल स्टम के जवाब को स्वीकार करें! – Joe

0

हालांकि, तो टूट जाता है आंतरिक संग्रह से अधिक की गणना करने में इसके अंदर है, क्योंकि सक्षम किया जा रहा कर।

यह मानते हुए कि आपके उचित तकनीक का पालन करें और IEnumerable और ICollection

लागू लेकिन मैं बजाय पहिया पुनर्रचना के प्रत्यक्ष संग्रह का प्रयोग करेंगे सच नहीं है।

और निश्चित रूप से आप जो भी चाहते हैं उसे करने के लिए Reactive extensions का उपयोग कर सकते हैं।

+0

मुझे नहीं लगता कि आपको आईसीओलेक्शन की आवश्यकता है। मुझे लगता है कि IENumerable पर्याप्त है। ऐसा कहा जाता है, ऐसा लगता है कि @ एंथनी पेग्राम का जवाब वह है जो उस मामले को संभालता है ... केवल आंतरिक संग्रह में प्रतिनिधि है। हालांकि, संग्रह से बेस क्लास को संग्रह पर बदलने के लिए बस चाल चलती है, इसलिए मैं इसे चिह्नित कर रहा हूं। – MarqueIV

2

मेरे सोचा बजाय सिर्फ बनाने के लिए एक सीधी वर्ग आंतरिक रूप से एक सूची का उपयोग करता है, और फिर मैं बस अपने खुद के जोड़ें बेनकाब कर सकते हैं/ तरीकों निकालें और करने के लिए समायोजन संभाल उपवर्ग सूची के बजाय करने के लिए है वहां 'अभिभावक'। हालांकि, ऐसा ब्रेक पर आंतरिक संग्रह से गणना करने में सक्षम होने के कारण अंदर है।

आप अभी भी अपने कस्टम संग्रह पर IEnumerable<Location> लागू कर सकते हैं। कक्षा के आंतरिक कार्यान्वयन विवरण के रूप में List<> का उपयोग करें, और आप इंटरफ़ेस के माध्यम से गणना की अनुमति दे सकते हैं।

class LocationList : IEnumerable<Location> 
{ 
    List<Location> _list; // initialize somewhere 

    public IEnumerator<Location> GetEnumerator() 
    { 
     return _list.GetEnumerator(); 
    } 

    IEnumerable.IEnumerator GetEnumerator() 
    { 
     return this.GetEnumerator(); 
    } 

    // ... your other custom properties and methods 
} 
+1

बेहतर हो सकता है कि ILI लागू करें, जिसमें IENumerable शामिल है, लेकिन यह उन संदर्भों में भी उपयोग करने की अनुमति देता है जो एक सूची, या कम से कम एक संग्रह चाहते हैं। – siride

+0

@ साइराइड, निश्चित रूप से, वह बीफियर 'IList ' लागू कर सकता है। यह अतिरिक्त कार्यक्षमता के साथ आता है जो वह प्रदान करना चाहता है या नहीं। मुद्दा यह नहीं था कि उन्हें किस इंटरफेस को लागू करना था। सच में, * उसे बिल्कुल इंटरफ़ेस को लागू करने की आवश्यकता नहीं है * (वह बस उचित 'GetEnumerator' विधि को परिभाषित कर सकता है), ऐसा करने के लिए यह बस अधिक मूर्खतापूर्ण है। –

+0

@ एंथनी, बस आपको यह बताने के लिए कि मैं इसे उत्तर के रूप में चिह्नित करने वाला था, लेकिन ऐसा लगता है कि हमारी सभी जरूरतों को पूरा करने के साथ ही करना आसान है, इसे संग्रह से संग्रह में बदलने के लिए है जो मुझे ओवरराइड करने देता है मुझे निम्न की जरूरत है।फिर भी, वास्तव में यह जानकर अच्छा लगा कि मैं सिर्फ गणना संग्रह को आंतरिक संग्रह में भेज सकता हूं इसलिए मैंने आपका वोट दिया। मुझे यह सोचना होगा कि क्या IList बनाम IENumerable बेहतर है ... IList हमारे लिए अधिक हो सकता है क्योंकि हम वास्तव में केवल अधिकांश भाग के लिए गणनाओं में रूचि रखते हैं, लेकिन इसका उपयोग करने में सक्षम होने पर सूची का उपयोग किया जाता है शांत है। – MarqueIV

0

आप या तो Observer pattern

+0

यह एक आंतरिक संग्रह के IENumerable इंटरफ़ेस को उजागर करने के लिए थोड़ा अधिक है। अगर मैं शुद्ध सबक्लास के साथ गया, तो ऑब्जेक्ट ग्राफ संरेखित नहीं होता है। ऐसा लगता है कि इस उपयोग-मामले के लिए उचित पैटर्न नहीं है। – MarqueIV

1

का उपयोग कर सकते हैं सामान्य BindingList<T> प्रयास करें, जब आइटम जोड़ा गया है और निकाल दिए जाते हैं जो घटनाओं को जन्म देती है।

+0

उपरोक्त कैनजेन के उत्तर में ObservableCollection के बारे में मेरी टिप्पणियां देखें। – MarqueIV

+0

@ मार्कक: आपको एहसास है कि वस्तुओं को जोड़ने के लिए समर्पित एक कार्यक्रम है, और संग्रह में परिवर्तनों का पता नहीं लगाया जाता है (आइटम स्वयं करते हैं, और केवल प्रकार जो INotifyPropertyChanged को कार्यान्वित करते हैं)। तो मुझे लगता है कि इस अतिरिक्त ओवरहेड के बारे में आप चिंतित हैं वास्तव में मौजूद नहीं है। प्रतिनिधि आमंत्रण और वर्चुअल फ़ंक्शन कॉल लगभग बिल्कुल वही लागत है। –

+0

असल में, जब आप सबक्लास में संग्रह ओवरराइड करते हैं (सूची ऐड/निकालने के कार्यान्वयन को ओवरराइड करने का समर्थन नहीं करता है), तो आप संदेश कॉल को स्वयं अवरुद्ध कर रहे हैं ताकि मूल संग्रह अभी तक यह नहीं पता कि कॉल को बढ़ाने के लिए बनाया गया था ऐसी अधिसूचनाएं इसके अलावा, संग्रह में घटनाओं को बढ़ाने के लिए नहीं है! यही है कि ObservableCollection के लिए है। और नहीं, वस्तुओं को स्वयं संग्रहों के बारे में नहीं पता है कि वे अकेले हैं या नहीं, इसलिए मुझे आपके आकलन से सम्मान से असहमत होना है। बस संग्रह subclassing मुझे देता है कि मैं क्या कर रहा हूँ। – MarqueIV

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