Collections for hierarchies - c#

In the app I am writing, I am trying to find a way to store hierarchies effectively. Here is an example.
At the bottom, you can see the nodes to be stored. Should I use multi dimensional lists? That doesn't seem very optimal, right? I was thinking holding references like so:
node.Parent
node.Children { collection }
Anyone has experience with this kind of stuff?

This is a fairly basic implementation of a tree, yes. If choose to make your collection for the children an IList or IEnumable or ArrayList, etc is up to you.
I would strongly suggest you build a generic implementation instead of one typed to your domain model, however that is up to you.

Yeah. You have the right idea. If you need a two-directional hierarchy, I wouldn't use a multi-dimensional list... I would add a node to the tree and each node contains a parent and a collection of children.
You are on the right track.

If not all items are of the same type, I may use an abstract base class for a linked list and children collections in such a situation.

Related

.NET tree object model

I like Microsoft's Windows Forms tree-view object model. It has the tree, nodes, children collection, parent, prev, next (sibling), etc. and search function. However I'm looking for the same object model with no UI - simply tree object model.
Does C# have this kind of model or do I have to implement it myself?
C# is a programming language. It does not have object models.
You may be asking whether the .NET Framework has a built-in "tree" class. It does not. You can build your own using the generic collection classes like LinkedList<T> and List<T>.
You could always use XML and the XML namespaces. It's got all the things you requested. Start with and XMLDocument and keep added XMLNodes and adding XMLNodes to the XMLNodes for children. Then you can use xpath queries to retrieve nodes.
An XmlDocument object is the closest match I can think of to your requirements. It supports parent, child, previous, next, sibling, etc. You can also use XPath to query the tree and return a specific node or sets of nodes. Also, because it's Xml you can easily import and export the data to/from a text file.
I suggest you read about binary trees on MSDN. It will teach you how to model tree data structures in code.
Good luck.

Children or Parent based Tree Structure

I'm developing a class that will be used to generate a tree structure. Each Node of the tree needs to know both who it's parent is and who it's children are. The fields used to track each Nodes parent and children are not accessible outside the base Node class.
Right now I have methods for AddChild, and Remove child. Which consequently also set the parent fields of the instances being related.
So what I'm wondering now is if it would be any better or worse to switch this and setup methods where the user of the class has to call Node.SetParent(Node parentNode) and Node.ClearParent(Node oldParentNode) methods instead.
If you are tracking both parent and child relationships, why would you choose to set the child relationships over the parents or vise versa, or does it even matter?
In either case, when you are attaching a node to the tree you will need a reference to both the parent and the child node in question, so I don't see how it would make a difference, as either way will be equally possible in all situations.
I'd suggest figuring out which direction your logic will make the most sense (i.e. is it easier to think about building the tree from the leaves up or the root down) and go with that.
Decisions like these typically depend on how the class will be used. If a typical scenerio is for a tree to be build from the parent node down, then using an AddChild method is often best, if your users build them from the other way around, give the a SetParent method. If there is a need for both, implement both, so long as the appropriate book keeping is done internal to the class.
(side note: I usually build trees from the parent down)
I think you need all three methods. When building a tree, the AddChild method would seem more natural. There are two reasons to remove a node. One is to get rid of it, and the other is to reorganise the tree (move a subtree to another branch). When deleting, RemoveChild works well. But reorganisation could use the SetParent method to avoid making two calls. SetParent could also become a transaction of sorts.

Hierarchy vs Merged List

Basically in my app I want to store all the nodes created by the user in a global list, say like:
GlobalComposition = { collection }
which will store nodes like:
ImageInput01, ImageInput02, Blur01, Sharpen01, Contrast01, Contrast02
What I can't decide is whether I should store them in a linear "1 dimensional" collection, or only store the base node that contains other nodes? So for something like:
ImageInput01 -> Blur01 -> Sharpen01 -> Contrast01
storing only ImageInput01.
This gives me the ability to use the same names for the action nodes that comes after the base node.
Which one would be better for unique naming system for nodes, performance, easily traversing the nodes in the composition, etc?
To me keeping the hierarchy seems more sensible but want to know people's thoughts.
Certainly a hierarchy will give you more power from a taxonomy point of view. Also, searching a tree is more efficient than searching a 1-dimensional collection in most cases.
You'd also be able to use .ToList() for a 1-dimensional collection as long as you're using .NET generic collections, as well.
Unfortunately, a hierarchy is a bit harder to implement, but generally if there is an indication of a need for it, you'll be able to take good advantage of the features it'll provide you way down the line.

Can I find Logical Children by Type

I know i can use LogicalTreeHelper class to find children node for every element searching it by name. But is there a possibility to find a child node by Type? For example, what if i would like to find a ListBox element in my Window without knowing its Name property??
I don't think that there is a built in way of doing this. Probably the best approach would be to recursively call LogicalTreeHelper.GetChildren() until a child control of the specified type is found.
Note that descending the Logical tree cleanly is actually a little tricky, here's a nice article on the intricacies of both the visual and logical trees.
I don't think any helper code exists to do this for you so implementing a recursive walk over the tree is required.

List of two different Types in C#

I'm currently having a problem with a ShoppingCart for my customer.
He wants to be able to add Text between the CartItems so I was wondering if there is some way to still only have one List.
My solution would be to have two lists, one of type IList that gets iterated over when calculating Weight and overall Price of the Cart while having another IList that only exposes the necessary fields for displaying it in the ListView and that is a SuperType of CartItem. (But how do I then access additional fields for the listView, defaulting weight and price to 0 in the Description-Text-Class would break LSP).
But having two lists somehow feels a bit odd (and still gives me problems), so I was wondering if I could do some sort of a TypedList where I specify the Type of each item.
Any suggestions are welcome, I'm not really happy with both options.
Use an interface:
ICartListItem
And make your list be:
List<ICartListItem>
Now, create several types, have all of them implement this interface, and you can store them all safely in your list.
Alternatively, if you want there to be some default logic in a CartItem, use a base class instead of an interface.
You can make a class and, inside of that, define the properties of the required list type and then make a list of same class.
For example, if I wanted to make a list of strings and bools, I would make two properties in one class and then make a list of that class.
The Interface sounds like overkill. I'd just add a property to your current CartItem named something like "TextAfterItem".
Also: make sure your customer understands the cost of this feature in terms of security overhead. It sounds like they think this should be a simple update, but you're allowing users to enter text that will be displayed directly back to the page, and that's a dangerous proposition.

Categories

Resources