• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 293
  • Last Modified:

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

0
Russ Suter
Asked:
Russ Suter
2 Solutions
 
Miguel OzSoftware EngineerCommented:
Yes if you change ClassB as follows:
Add a new constructor:
public ClassB(ClassA parent)
{
     this.Parent = parent;
}
and the id :
public string GetParentId()
{
    return this.Parent.ID;
}

Your code will look like:


ClassA.ID = Guid.NewGuid(); 
ClassA.ClassBCollection.Add(new ClassB(ClassA)); 
 
Print ClassA.ClassBCollection[0].GetParentID;

Open in new window

0
 
Richard QuadlingSenior Software DeverloperCommented:
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;}
0
 
Russ SuterAuthor Commented:
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.
0
NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

 
Miguel OzSoftware EngineerCommented:
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.
0
 
johnboumaCommented:
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);
0
 
anarki_jimbelCommented:
I believe the only way to achieve your goal to use references as was suggested above.

Concerning adding a B object to others A collection. I encountered same problem somewhere. One way is to create a special method on the A class to add objects to the collection. I.e you add not like:

A.BCollection.Add

but:

A.AddToBCollection(B);// sets reference for the right A class.

There is another issue here: it is still possible to access underlying collection and still add directly.
One way is to protect this collection somehow. Another way is to write custom collection that has a reference to the containing  A class (and therefore customized Add method could be used to set proper ID).
0
 
Russ SuterAuthor Commented:
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?
0
 
Russ SuterAuthor Commented:
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.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now