Link to home
Start Free TrialLog in
Avatar of Russ Suter
Russ Suter

asked on

Getting a parent property

I have written a class (call it ClassA) that, as one of its properties, has a collection of another class (call it ClassB).

Is there any way for items in the Collection<ClassB> to return the ID property of the containing ClassA? As an example, I have included pseudo code to indicate what I want to do.
ClassA.ID = Guid.NewGuid();

ClassA.ClassBCollection.Add(new ClassB());

Print ClassA.ClassBCollection[0].ParentID;

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Miguel Oz
Miguel Oz
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
One thing to watch out for in infinite recursion.Whenever you have object A references object B which references object A, any code which doesn't track which objects it has looked at can follow the links indefinitely.This may not be an issue for the tools in .NET but if you have code which can report the object contents, you could see problems there.One way is to help here is to only store the ID rather than a reference to the actual instance.public ClassB(ClassA parent){     this.ParentID = parent.ID;}and the id :public string GetParentId(){    return this.ParentID;}
Avatar of Russ Suter
Russ Suter

ASKER

I've considered that but what happens if I move the instance of ClassB to a collection in another instance of ClassA? The parent reference is now broken.
If you moved ClassB instance, you just need to update the the parent field to the instance of the new parent. (It implies to build Parent as a get/set property of ClassB.
Probably the best way to do this is to pass a reference to classA into the calssB constructor.  

IE
public class ClassB
{
     ClassA caObjRef;

public ClassB( ClassA caObj)
{
     caObjRef = caObj;
}

be sure to clean house by implementing a destructor...

public ~ClassB()
{
    caObjRef=null;
}


in classA

...
...
ClassBCollection = new ClassB(this);
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
What about using techniques like reflection or stack trace? It must be possible. Look at the System.Web.UI.Control base class. Somehow they've managed to implement a Parent property that works without passing additional references. Just give it a try. Create a web page and then in code create a control and add it to the Controls collection of the page. Then reference the control's parent property and the page is there in all its glory. How does that work?
I've found a way to make this work using a custom collection class derived from System.Collections.CollectionBase.

The Collection class has 3 constructors. The first two are the standard public constructors

public CollectionBase();
public CollectionBase(int capacity);

The third is an internal constructor.

internal CollectionBase(BaseClass parent);

I then made sure that all methods that insert an element into the List set the Parent property of the class being inserted. As a result, the Insert method, for example, looks something like this:

        public void Insert(int index, ClassB item)
        {
            item.Parent = this.Parent;
            List.Insert(index, item);
        }

This way the reference is correctly maintained automatically if the instance is added to a different collection. The only issue is that it IS possible to have an instance belong to more than one collection. In this case the Parent property would only point to the most recent parent. This is an acceptable issue since I won't ever be adding the instance to multiple Collections.