2 ответов:
Вот общий пример того, как можно пересечь составной объект:
public static class TraversalHelper{ public static void TraverseAndExecute<T>(this T composite, Func<T,IEnumerable<T>> selectChildren, Action<T> action) where T: class { action.Invoke(composite); composite.TraverseAndExecute(selectChildren, action, new List<T>{ composite }); } private static void TraverseAndExecute<T>(this T composite, Func<T,IEnumerable<T>> selectChildren, Action<T> action, IList<T> invokedComponents) where T: class { invokedComponents = invokedComponents ?? new List<T>(); var components = selectChildren(composite) ?? new T[]{}; foreach(var component in components){ // To avoid an infinite loop in the case of circular references, ensure // that you don't loop over an object that has already been traversed if(!invokedComponents.Contains(component)){ action.Invoke(component); invokedComponents.Add(component); component.TraverseAndExecute<T>(selectChildren, action, invokedComponents); } else{ // the code to execute in the event of a circular reference // would go here } } } }Вот пример использования:
public class Program{ public static void Main(){ var someObject = new SomeObject { Name = "Composite", SomeObjects = new List<SomeObject>{ new SomeObject{ Name = "Leaf 1" }, new SomeObject{ Name = "Nested Composite", SomeObjects = new List<SomeObject>{ new SomeObject{Name = "Deep Leaf" }} } } }; someObject.TraverseAndExecute( x => x.SomeObjects, x => { Console.WriteLine("Name: " + x.Name); } ); } }
Это древовидная структура; существует множество алгоритмов для ее обхода, вы можете искать алгоритмы обхода дерева, и вы найдете многие из них.
Comments