The correct way to set the parent of a node tree in C #?

I am working on a custom tree. Each node (BindingNode - as I call them) contains a BindingNodeCollection that implements ICollection and contains more nodes. My problem is that the user must have access to each node parent with the readonly property called Parent, as in TreeNode . But nodes are added to the BindingNodeCollection by calling the BindingNodeCollection Add(BindingNode node) method. The BindingNodeCollection knows that it has a parent, but cannot assign a BindingNode Parent in the Add(BindingNode node) method, because the Parent must be read-only. The functionality I'm trying to achieve is basically the same as the functionality of TreeNode and TreeNodeCollection in TreeView :

-TreeNode Parent is read-only.

-TreeNodes are assigned to the TreeNodeCollection by calling the TreeNodeCollection Add(TreeNode node) method.

-TreeNode Parent provides a TreeNode that contains the TreeNodeCollection where the TreeNode was added.

-TreeNodeCollection is NOT defined inside TreeNode to have access to the parent private field.

This is when I missed C ++ friend . friend

+3
source share
5 answers

There are several ways that you can achieve what you need, it really depends on what kind of security you need. Is this a library or a closed application that only affects you or your colleagues? Here are some tips and questions to consider before you go with them.

  • Make the property setter on the BindingNode internal; Do you trust everyone in this meeting to not orphan the children?

  • Highlight the BindingNodeCollection as ReadOnly and provide methods to change the collection on the BindingNode itself. An application can set the Parent property. Delete is required to return the parent property to null. It's pretty locked up, polluting your base class node worth peace of mind?

  • Accept that transparency is more important than security for you and expose the parent setter as public. Do you trust everyone who can see your classes not for orphans?

For further reading, and possibly better ideas, what you are almost describing is the Composite Pattern . There is a TON discussion of security and transparency for this template, and most of them are related to the fact that these classes are used by the public for use in some APIs. This may be redundant for your situation, or it may be exactly what you need to consider, I do not know if your question has given what the scope is.

+2
source

The C # internal modifier is equivalent to the friends class to make the parent SET method available only to classes within the same assembly.

 TreeNode Parent { get; internal set;} 
+2
source

I think this is called a decorator pattern? Come on, if I'm right. I never remember the name of the template.

I would create a class that was built in add and when built, has a Parent property property and just has node as a member. If there is an interface for BindingNode, then I would implement an interface with all the methods and properties passing through the real BindingNode.

 public class BoundNode : INode { private INode _thisNode { get; private set; } public INode Parent { get; private set; } public BoundNode(INode bindingNode, INode parent) { _thisNode = bindingNode; Parent = parent; } // Implement pass throughs to the _thisNode member } 

Then the add method implements

 public Add(INode someNode) { _nodeList.Add(new BoundNode(someNode, this.Parent)); } 

Or something like that ... however your collection knows about this node context ..

+1
source
 public class BindingNode { private BindingNode _parent; private List<BindingNode> _children = new List<BindingNode>(); public IEnumerable<BindingNode> Children { get { return _children; } } public BindingNode Parent { get { return _parent; } } public void AddChild( BindingNode node ) { node._parent = this; _children.Add( node ); } } 
+1
source

The correct way is to assign the child element node to the parent element. Like this:

 parentTreeNode.Nodes.Add(childTreeNode); 
0
source

Source: https://habr.com/ru/post/1012663/


All Articles