Exposing child objects

Consider a business object that has a list of child objects. Let's assume that the parent has to do some housekeeping operations when children are added or removed, and also has some rules what children are legal to add.

Before delving into various solutions using collections, let's consider the problem of ownership of the data returned from an object.

While the access scenario of

foreach( FooChild child in Foo.Children)

is the desirable one, there is no stopping someone from doing

FooChildren[] children = Foo.Children;

and then carrying the collection around. Of course, the moment the collection changes inside Foo, the child collection retrieved is invalid, since it was an array and not re-sizable. Would that violate your expectations? I generally consider Properties to be Accessors, i.e. you get the value used by the object, not some clone for you to manipulate without affecting the originating data. And the above scenario would violate that expectation.

So are Properties really an object's data and results retrieved from a method such as GetChildren data for you to manipulate without an expectation of changing the data in the originating object? If not, can the rules governing retrieved data be expressed in code, or is this type of contract something that is only going to be communicated through documentation?

If we proceed that the expectation is that once you get a collection back from a property it's still associated with the parent we get behavior similar to Xml Nodes. That solution would look something like this:

foo.Children.Add(new FooChild());

Pre-C# 2.0, you'd have to create your own strong-typed collection object for the children. If you do this more than a couple times, that's a lot of repeated code, what with all IEnumerable requirements. But it does provide you the added benefit that you could define events for the parent to be notified when things happened, so it could execute its constraint logic, which an untyped arraylist would not.

In 2.0, the whole thing could be done with an ICollection or, even better, an IList. But you'd still have to write that generic class yourself because (AFAIK) there are no implementations that have events to notify you when the collection changes. All things considered, though, this promotes much better re-use and a cleaner interface.

Or is there a better pattern to follow that i've not touched on?