1

I have a class that exposes different types of collections as properties, like List<Address> and SortedSet<string>. I understand collection classes should be read-only, that we should not expose a collection for update, like person.Address[3].City = "MyTown", or person.EmailAddresses.Add("foo@bar.tld"). I'm looking for a C# pattern to support this.

My requirements are a bit unique because my classes (like Person in this example) implement INotifyPropertyChanged. So when a change is made to these collections I want to fire an event on the container object (person) to notify the client application. I know we can use ObservableCollection<T>, and for the SortedSet there are examples like this and this of derived classes that maintain sorted storage. I'm trying to avoid adding a custom class to my project for other developers who make use of this Person class - I'd prefer to expose only CLR classes to reduce the need for a client application to manipulate other structures but that's not a requirement.

Most solutions to this problem of sorted storage are "don't store sorted data, let the client view do it", but that leaves the common function of sorting to developers who are consuming this class, each taking individual time to create their own implementation in a different technology (WPF components, LINQ, etc.). And in this example, the Person class wraps another more primitive class, where for example my SortedSet<string> Email property would have a setter that creates an EMAIL[] array. When serialized that array needs to sorted for legacy purposes, and where the base type is sorted I want to expose a sorted generic collection.

I've also read you should not raise the PropertyChanged event when the contents of the collection change. Well, in this case the client application does need to know whenever any kind of change is made to this object and arguments about why that shouldn't be done don't agree with the reality that we actually need it.

In summary, I'm looking for a consistent C# design pattern for modifying a collection encapsulated within a container object, where the collection might be sorted, where the collection elements might be value types or reference types, and where the client application using this object must receive change notifications of all changes.

At this point I'm inclined to do this entirely with methods, creating a consistent API for this Person class for all collection types, to get the entire collection object perhaps as a strongly typed class rather than as a generic CLR collection, replace instance properties with such an object, set elements, and clear it. But I'd really rather just be doing all of this with common getter/setters.

Community
  • 1
  • 1
TonyG
  • 1,432
  • 12
  • 31
  • Have you seen the ReadOnlyObservableCollection class? I think it should meet all your needs. – aKzenT Sep 17 '14 at 20:42
  • *you should not raise the PropertyChanged event when the contents of the collection change.* - but the collection raises a [`INotifyCollectionChanged`](http://msdn.microsoft.com/en-us/library/system.collections.specialized.inotifycollectionchanged%28v=vs.110%29.aspx) event however! It's not a PropertyChanged per se, but rather a more fine tuned "my collection has changed" event. So listeners can certainly get a notification of when the collection changes. – default Sep 17 '14 at 20:53
  • [this](http://msdn.microsoft.com/en-us/library/ms182327.aspx) does not mean "don't notify anyone if the collection changes". It just means that you shouldn't expose a setter for your collections. – default Sep 17 '14 at 20:59
  • @aKzenT, good suggestion. But I'd probably need to make a derived class for that to make it sortable - I haven't found any. If I'm going to do that I might as well create a new collection accessor class, breaking my preference to keep everything at the BCL/CLR. But I'll continue to read-up on that and will consider it. Default: I get the subtlety, and it works in this scenario. Will work it into the final solution. Thx – TonyG Sep 17 '14 at 21:01

0 Answers0