using NUnit.Framework; using System; using System.Collections.Generic; namespace GenericTree { /// /// Generic tree interface /// /// /// interface ITreeNode where T : ITreeNode { bool IsValid { get; } int ValueIndex { get; } U Value { get; } bool HasParent { get; } T Parent { get; } IEnumerable Children { get; } } /// /// Item has parent reference by list index /// public interface ITreeItem { int ParentIndex { get; } } /// /// Generic tree implementation /// /// struct TreeNode : ITreeNode, T> where T : ITreeItem { /// /// Whole tree nodes /// public readonly List Values; public bool IsValid { get { return Values != null; } } /// /// This node index /// public int ValueIndex { get; private set; } public T Value { get { if (Values == null) { return default(T); } return Values[ValueIndex]; } } public IEnumerable> Children { get { for (int i = 0; i < Values.Count; ++i) { if (Values[i].ParentIndex == ValueIndex) { yield return new TreeNode(Values, i); } } } } public bool HasParent { get { return Value.ParentIndex >= 0 && Value.ParentIndex < Values.Count; } } public TreeNode Parent { get { if (Value.ParentIndex < 0) { throw new Exception("this may root node"); } if (Value.ParentIndex >= Values.Count) { throw new IndexOutOfRangeException(); } return new TreeNode(Values, Value.ParentIndex); } } public TreeNode(List values, int index) : this() { Values = values; ValueIndex = index; } } class TreeTests { [Test] public void TreeTest() { } } }