При работе с деревьями в объектной модели я считаю более полезным, если у объекта есть Children. Хотя легче поддерживать Родителя, как вы делаете. Фактически, вы можете абстрагировать дерево в общий интерфейс или два:
public interface IHaveChildren<out T> where T:IHaveChildren<T>
{
/// <summary>Gets the children.</summary>
IEnumerable<T> Children { get; }
}
public interface IHaveFamily<out T> : IHaveChildren<T> where T : IHaveChildren<T>
{
/// <summary>Gets the Parent.</summary>
T Parent { get; }
}
Теперь вы можете установить множество интересных и полезных расширений, чтобы получать древовидную информацию, не заставляя вашего бедного сотрудника тоже беспокоиться об этом! Вот два таких расширения, которые используют преимущества этих интерфейсов.
public static class HeirarchyExtensions
{
public static bool IsAncestorOf<T>(this IHaveFamily<T> instance1, IHaveFamily<T> instance2) where T : IHaveFamily<T>
{
if(instance1.IsLeaf()) return false;
foreach (var child in instance1.Children)
{
if (child.Equals(instance2)) return true;
return instance1.IsAncestorOf(child);
}
return false;
}
public static IEnumerable<T> GetDescendents<T>(this IHaveFamily<T> instance) where T : IHaveFamily<T>
{
var result = instance.Children;
if(!result.Any())
return result;
foreach (var child in instance.Children) {
result = result.Concat(child.Children);
}
return result;
}
}
НТН,
Berryl