using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Application { public static class TopologicalSorter { /// /// Returns a set of items sorted by topological order. /// /// The element type of the sequence. /// The source. /// The dependencies. /// If set to true cyclic dependency is not allowed. /// The sorted sequence. public static IEnumerable TplgSort(this IEnumerable source, Func> dependencies, bool throwOnCycle = false) { var sorted = new List(); var visited = new HashSet(); foreach (var item in source) { Visit(item, visited, sorted, dependencies, throwOnCycle); } return sorted; } private static void Visit(T item, HashSet visited, List sorted, Func> dependencies, bool throwOnCycle) { if (visited.Contains(item) == false) { visited.Add(item); foreach (var dep in dependencies(item)) { Visit(dep, visited, sorted, dependencies, throwOnCycle); } sorted.Add(item); } else { if (throwOnCycle && sorted.Contains(item) == false) { throw new Exception("Cyclic dependency found"); } } } } }