Is there an accepted method of adding possibly-derived objects to a collection without allowing instances of the base or derived objects to be created on their own? I’m thinking that’s almost a contradiction in terms.
About the only method I’ve been able to come up with is to add to the parent collection from the child’s base implementation like this:
// Child constructors
private void Child() { }
protected void Child(Parent parent)
{
parent.Collection.Add(this);
}
This forces the child object to always be instantiated with a parent, but it seems like a rather messy implementation to add a child class to a parent collection from the child. I know I can pass a Type-type variable to a method, and this might be the way to go, but I’m not sure how to create/cast to the passed type.
Update: I’m playing around with code that looks like this as a possible generic ChildCollection.Add method, in case this gives anybody a better picture of what I want…we’ll see if it works in the long run:
// Currently testing directly in Parent class;
// can later be moved/modified for Parent's ChildCollection class.
public Child AddTest(string info, Type derivedType)
{
ConstructorInfo ci = derivedType.GetConstructor(new Type[] { typeof(Parent) });
Child myBaby = (Child) ci.Invoke(new Object[] { this });
myBaby.Initialize(info);
return myBaby;
}
This could then be called with code like:
Child newChild = Parent.AddTest("Hello World", typeof(DerivedChild));
Ultimately, I’ve gone for code very similar to what I posted in my update. I’m posting it here, as I think it’s a useful technique for either a generic object factory or a limited one (in this case, limited to those that derive from the Child class).
The basic idea is to create a custom collection, then use an Add method (or perhaps I should name it Create?) to instantiate the object and properly handle any overridden initialization in a Child derivative.
Here’s a skeleton of the code I ended up with:
Since this may not cover every possible derived Child the client application might want to create (particularly if they’re adding their own parameters to the constructor), I’m thinking I’ll probably also provide an Add(Child child) method, with the caveat that if the user is instantiating the Child object with a standard “new Child(Parent)”, they’re also responsible for taking all the standard initialization steps in the expected manner.