Is there a good sample for publishing a general collection as read-only?

So, I have these classes that expose a collection of child objects.

I do not want other classes to add or remove objects from collections, because I need to connect to events of child objects, since they are added or deleted, I want to be able to perform additional processing. But I really like to easily manipulate generics inside.

I mentioned that this is a WPF application, so do I need INotifySupport?

The best I can come up with is something like this.

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(); } } } 

Are there any serious flaws in this design that I don’t see?

Each time access to the "Children" resource, we get the overhead of converting the list into an array.

Any advice on this would be great.

+6
generics c # design-patterns architecture wpf
source share
4 answers

You must use the ObservableCollection field as in your class, then you have full access to modify the collection. Then expand it as ReadonlyObservableCollection through the property. And if you do not change the collection itself (for example, no children = new ObservableCollection() , you must make the field read-only), then you do not need any kind of notifyPropertyChanged for this property, because it does not change, and the collection itself processes these events for your children.

 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); } } } 
0
source share

This is what I do for regular code:

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

For WPF code, I would just open a subclass of ObservableCollection.

+5
source share

I changed "add child" and "remove child" to protected, since you say that you do not want other classes to modify your collection. I changed my list to ObservableCollection so that you can receive notifications of changes to the collection. Since you are using IList, there is no need to call ToArray (), just access directly.

try the following:

 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
source share

You can subclass the BindingList and set AllowNew / AllowRemove to false. In the methods for adding / removing your child, you can set it to true, make changes, and then set it to false. (Of course, you need to hide the established access to AllowNew / AllowRemove from external callers).

Another option is to subclass the Observed Collection and override the InsertItem, RemoveItem, etc. methods that will behave like AddChild / RemoveChild. Then callers can access it in familiar ways, but not bypass your user logic.

Subclassing an existing collection class is likely to be easier (for you and the consumer) than packing the collection into another class.

0
source share

All Articles