LasseVK.TopoSort
1.0.0
dotnet add package LasseVK.TopoSort --version 1.0.0
NuGet\Install-Package LasseVK.TopoSort -Version 1.0.0
<PackageReference Include="LasseVK.TopoSort" Version="1.0.0" />
<PackageVersion Include="LasseVK.TopoSort" Version="1.0.0" />
<PackageReference Include="LasseVK.TopoSort" />
paket add LasseVK.TopoSort --version 1.0.0
#r "nuget: LasseVK.TopoSort, 1.0.0"
#:package LasseVK.TopoSort@1.0.0
#addin nuget:?package=LasseVK.TopoSort&version=1.0.0
#tool nuget:?package=LasseVK.TopoSort&version=1.0.0
LasseVK.TopoSort
This package adds methods and types for topological sorting, a graph algorithm that determines a valid ordering of vertices in a directed acyclic graph (DAG) such that for every directed edge (u, v), vertex u comes before vertex v in the ordering.
The package provides a set of extension methods that does this ordering.
Note: Portions of this library were added by AI, given that I have an IDE that uses AI-style autocompletion. There is however, no portion of it not vetted by me.
Discord
You can reach me through my Discord server.
Nuget package
You can find the Nuget package here.
Installation
You can install the package from the command line, using dotnet:
dotnet add package LasseVK.TopoSort
Or you can use your favorite IDE which should have a Nuget package manager built in.
Framework support
The package supports the following .NET versions and standards:
- .NET 8.0 (until november 10, 2026)
- .NET 9.0 (until november 10, 2026)
- .NET 10.0 (until november 14, 2028)
- .NET Standard 2.0
- .NET Standard 2.1
This follows the official supported versions policies from Microsoft:
Note: After support for a .NET version ends, the package will still exist on nuget for use with that version, but I won't guarantee that updates to that version will be made.
Usage
The project relies on the code providing the added methods with a list of dependencies, indicating which values follow from which other values (dependents depends on dependencies).
You can specify the dependencies in a variety of ways, including using the TopologicalSortEdge class or tuples.
var dependencies = [
new TopologicalSortEdge<int>(1, 2),
new TopologicalSortEdge<int>(2, 3),
new TopologicalSortEdge<int>(3, 4),
new TopologicalSortEdge<int>(4, 5),
];
var sorted = dependencies.Ordered().ToList();
// sorted will be [1, 2, 3, 4, 5]
When using ValueTuple<T1, T2> or Tuple<T1, T2>, in order to not conflict with existing
sorting methods in .NET, the name of the method will be TopoOrdered, like this:
var dependencies = new ValueTuple<int, int>[]
{
(1, 2),
(2, 3),
(3, 4),
(4, 5),
}
var sorted = dependencies.TopoOrdered().ToList();
// sorted will be [1, 2, 3, 4, 5]
IEqualityComparer and IComparer
The methods all have two optional arguments:
IEqualityComparer<T> equalityComparerwhich will be used to determine if vertex values being used are the same. This defaults toEqualityComparer<T>.Defaultif no specific equality comparer is being specified.IComparer<T> comparerwhich will be used to determine the order of vertices that are otherwise unrelated. This defaults toComparer<T>.Defaultif no specific comparer is being specified. See more about this at the bottom of the notes section.
Notes and remarks
Vertices will not be duplicated, and each vertex in the dependency graph are produced just once in the final result. There is no support for having duplicate vertices. However, given that a
IEqualityComparer<T>is involved, this can be mimicked with a custom made implementation.There is no built-in support for vertices not involved in any dependencies. Loose vertices will have to be handled outside of these ordering methods.
Cycles in the graph will result in an
InvalidOperationExceptionbeing thrown. This involves multi-vertex cycles, such as1-->2, 2-->3, 3-->1, as well a self-referencing edges, such as1-->1.Distinct dependencies, ie. dependencies that have no bearing on each other, will result in an output that contains all the dependencies together, before all the dependents together. In other words, the following set of dependencies:
1 --> 2 3 --> 4will result in the following output:
1, 3, 2, 4 ^+-^ ^+-^ | | | +- dependents +- dependencies
The way these values are output is that the algorithm finds first the group of values that is 1 and 3,
then outputs those, and then afterwards it finds 2 and 4 and outputs those.
Each of these sets contain vertices that are otherwise unrelated (ie. there is no relationship between
1 and 3), and in this case, the optional IComparer<T> instance, if specified, can be used to determine
the final output ordering of all the values in a given set.
Given an IComparer<int> implementation that results in a reversed order, it would thus be possible to
get the following output instead:
3, 1, 4, 2
however, the edge dependencies are what guarantees that 1 comes before 2 and that 3 comes before 4,
and nothing the IComparer<T> instance does will change that.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
-
.NETStandard 2.1
- No dependencies.
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 94 | 5/13/2026 |