2010-10-08 8 views
6

तो मुझे ये कक्षाएं मिली हैं जो बाल वस्तुओं के संग्रह का पर्दाफाश करती हैं।क्या सामान्य संग्रह को पढ़ने के लिए एक अच्छा पैटर्न है?

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

क्या मैंने इसका उल्लेख किया है कि यह एक WPF ऐप है इसलिए मुझे INotifySupport की आवश्यकता है?

सबसे अच्छा मैं इस तरह से कुछ कर सकता हूं।

public class foo : INotifyPropertyChanged 
{ 
    protected List<ChildFoo> _Children = new List<ChildFoo>(); 

    public foo() 
    { 
    } 

    public void AddChild(ChildFoo newChild) 
    { 
     DoAttachLogic(newChild); 
     _Children.Add(newChild); 
     NotifyPropertyChange("Children"); 
    } 

    public void RemoveChild(ChildFoo oldChild) 
    { 
     DoRemoveLogic(oldChild); 
     _Children.Remove(oldChild); 
     NotifyPropertyChange("Children"); 
    } 

    public ChildFoo[] Children 
    { 
     get 
     { 
      return _Children.ToArray(); 
     } 
    } 

} 

क्या इस डिज़ाइन के साथ गंभीर त्रुटियां हैं जिन्हें मैं नहीं देख रहा हूं?

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

इस पर कोई सलाह बहुत अच्छी होगी।

+1

नोटिफ़ाईप्रॉपर्टी चेंज ("बच्चे") मत बढ़ाएं क्योंकि एक बच्चा ऑब्जेक्ट बदल गया है। आप पूरे संग्रह को पुनर्जीवित नहीं करना चाहते हैं। –

+2

सूची के बजाय, ObservableCollection पर विचार करें। यह संग्रह परिवर्तन घटनाओं को लागू करता है जो डब्ल्यूपीएफ की अपेक्षा करता है। एक और विकल्प INotifyCollection को सीधे लागू करना है। –

+0

सही लेकिन ऑब्जर्वेबल कोलेक्शन के साथ समस्या यह है कि कोई प्रोग्रामर अब AddChild() विधि का उपयोग किये बिना सीधे संग्रह में जोड़ सकता है। यदि ऐसा करने का कोई तरीका था तो मैं दिल की धड़कन में देखने योग्य उपयोग करता। –

उत्तर

0

आपको ऑब्जर्जेबल कोलेक्शन को अपनी कक्षा में फ़ील्ड के रूप में उपयोग करना चाहिए, फिर आपके पास संग्रह को संशोधित करने के लिए पूर्ण पहुंच है। फिर इसे संपत्ति के माध्यम से ReadonlyObservableCollection के रूप में बेनकाब करें। और यदि आप संग्रह को स्वयं नहीं बदलते हैं (उदाहरण के लिए children = new ObservableCollection(), आपको क्षेत्र को केवल पढ़ना चाहिए), तो आपको किसी भी प्रकार की अधिसूचना की आवश्यकता नहीं है प्रॉपर्टी इस संपत्ति पर बदल दिया गया है, क्योंकि यह नहीं बदलता है और संग्रह स्वयं अपने बच्चों के लिए उन घटनाओं को संभालता है।

public class Child 
{ 
    public int Value { get; set; } 
} 

class MyClassWithReadonlyCollection 
{ 
    private readonly ObservableCollection<Child> _children = new ObservableCollection<Child>(); 

    public MyClassWithReadonlyCollection() 
    { 
     _children.Add(new Child()); 
    } 

    //No need to NotifyPropertyChange, because property doesnt change and collection handles this internaly 
    public ReadOnlyObservableCollection<Child> Children { get { return new ReadOnlyObservableCollection<Child>(_children); } } 
} 
5

यह है कि मैं क्या सामान्य कोड के लिए क्या है:

Public Readonly Property Childern As ObjectModel.ReadOnlyCollection(Of Child) 
    Get 
     Return New ObjectModel.ReadOnlyCollection(Of Child)(_ChildernList) 
    End Get 
End Property 

WPF कोड के लिए मैं सिर्फ ObservableCollection का एक उपवर्ग को बेनकाब करेंगे।

+0

-1 मुझे आशा है कि आप यह सुझाव नहीं दे रहे हैं कि सी # डेवलपर्स बुनियादी पढ़ने के लिए पर्याप्त स्मार्ट नहीं हैं। – Tergiver

+0

के जवाब में वीबी के उपयोग के लिए –

+0

गंभीरता से मैं वीबी पढ़ सकता हूं ठीक है धन्यवाद। –

0

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

इस प्रयास करें:

public class foo : INotifyPropertyChanged 
{ 
    protected ObservableCollection<ChildFoo> _Children = new ObservableCollection<ChildFoo>(); 

public foo() { } 

protected void AddChild(ChildFoo oldChild) 
{ 
    DoAttachLogic(newChild); 
    _Children.Add(newChild); 
    NotifyPropertyChange("Children"); 
} 

protected void RemoveChild(ChildFoo oldChild) 
{ 
    DoRemoveLogic(oldChild); 
    _Children.Remove(oldChild); 
    NotifyPropertyChange("Children"); 
} 

public ChildFoo this[int n] 
{ 
    get 
    { 
     return _Children[n]; 
    } 
} 

} 
+0

वैसे मैं चाहता हूं कि लोग संग्रह को बढ़ाने या घटाने में सक्षम हों, लेकिन मुझे कक्षा में जाने के लिए उन्हें जाने की ज़रूरत है, इसलिए मैं उन वस्तुओं पर अतिरिक्त तर्क चला सकता हूं जिन्हें जोड़ा/हटाया जा रहा है। –

+0

इसलिए, मूल रूप से आप जो चाहते हैं वह एक सूची के चारों ओर एक रैपर है। मैंने जो कोड दिया है, उसमें सार्वजनिक रूप से संरक्षित ऐड/हटाएं, और आपको सुनहरा होना चाहिए –

0

आप BindingList उपवर्ग और गलत पर AllowNew/AllowRemove सेट कर सकते हैं। अपने बच्चे में विधियों को जोड़ें/निकालें, आप इसे सत्य पर सेट कर सकते हैं, परिवर्तन कर सकते हैं, फिर इसे वापस गलत पर सेट कर सकते हैं। (बेशक, आपको बाहरी कॉलर्स से AllowNew/AllowRemove पर सेट एक्सेस को छिपाने की आवश्यकता है)।

एक और विकल्प - सबक्लास अवलोकन संग्रह और InsertItem, RemoveItem, आदि विधियों को ओवरराइड/RemoveChild के रूप में व्यवहार करने के तरीके को ओवरराइड करेगा। फिर कॉलर अभी भी परिचित तरीकों से इसका उपयोग कर सकते हैं, लेकिन अपने कस्टम तर्क को बाईपास नहीं कर सकते हैं।

किसी मौजूदा संग्रह वर्ग को उप-वर्गीकरण करना संभवतः किसी अन्य वर्ग में संग्रह को लपेटने से आसान (आपके और उपभोक्ता के लिए) होना आसान है।

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