Parent in child class

A real world example is pretty simple. There is a house, and the house has walls, etc.

class Room { public List<Wall> Walls{get; set;} } class Wall { public List<WallObject> WallObjects{get; set;} } 

Now the developer added a property room to the class wall a few years ago:

 class Wall { public List<WallObject> WallObjects{get; set;} public Room Room{ get; set; } } 

It is very nice to have this object in the classroom. One has access to the parent in many places (430). But I think that it does not belong there and sometimes leads to errors, because you do not install it or change it.

Are there other approaches, with the exception of handoff methods in many cases.

+5
source share
2 answers

There are several ways to fix this easily, but usually I would like to change the type of list used and use the appropriate events to register and unregister the parent.

 public class Room { public ObservableCollection<Wall> Walls { get; } = new ObservableCollection<Wall>(); public Room() { Walls.CollectionChanged += Walls_CollectionChanged; } private void Walls_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case NotifyCollectionChangedAction.Add: { foreach (Wall w in e.NewItems) { w.Room = this; } break; } case NotifyCollectionChangedAction.Remove: { foreach (Wall w in e.OldItems) { w.Room = null; } break; } } } } 
+1
source

You are right, the information is redundant. It is always possible that the List<Wall> in a Room may contain walls; the Room property refers to another room, which would be an error. Therefore, either remove it from Wall , or make sure that each Wall is checked in the Walls installer. If the Room wall is != this , you can throw an exception or change it.

So, I would change the Room class a bit:

 public class Room { private List<Wall> walls; public Room(): this(new List<Wall>()) { } public Room(List<Wall> walls) { this.Walls = walls; } public List<Wall> Walls { get { return this.walls; } set { foreach (Wall wall in value) { if (wall?.Room != this) { throw new ArgumentException("Every wall room must be this Room instance", nameof(Walls)); } } this.walls = value; } } } 

Since there are usually 4 walls in a room, this should not be a big problem.

+1
source

All Articles