Apariencia
Recorrer árboles y navegar
TreeTraversal pertenece a Greencore.Platform.Errors.Trees y funciona sin Result. Usa las consultas de Error para búsquedas habituales; usa el recorrido cuando necesitas ramas, hojas o rutas completas.
Árbol del ejemplo
csharp
using System;
using System.Linq;
using Greencore.Platform.Errors;
using Greencore.Platform.Errors.Extensions;
using Greencore.Platform.Errors.Trees;
using Greencore.Platform.Nodes;
var error = Error.Create("Importación fallida.");
var fila = error.AddReason(new Reason("Fila inválida."));
fila.AddReason(new Reason("Nombre obligatorio."));
fila.AddReason(new Reason("Correo inválido."));
error.WithReason("Archivo incompleto.");
var traversal = new TreeTraversal();Los bloques siguientes continúan este ejemplo.
Métodos públicos
| Método | Resultado | Nodo inicial |
|---|---|---|
EnumerateNodes(IErrorNode) | IEnumerable<INode> | Incluido |
EnumerateDescendants(INode) | IEnumerable<INode> | Excluido |
EnumerateLeaves(IErrorNode) | IEnumerable<INode> de hojas | Incluido si es hoja |
EnumerateLeafPaths(IErrorNode) | IEnumerable<IReadOnlyList<INode>> | Incluido en cada ruta |
EnumerateLeafPaths(INode) | Lo mismo, desde cualquier nodo | Incluido en cada ruta |
TreeTraversal.Children(INode) | IReadOnlyList<INode> de hijos inmediatos | Excluido |
INode expone Message y Metadata; no declara Reasons. Usa Children para obtener hijos sin distinguir IErrorNode de IReasonNode. Si no implementa ninguno de esos dos contratos, devuelve una lista vacía.
Recorrer nodos y ramas
csharp
foreach (var nodo in traversal.EnumerateNodes(error))
Console.WriteLine(nodo.Message);
var primeraCausaDeFila = traversal.EnumerateDescendants(fila)
.OfType<IReasonNode>()
.FirstOrDefault();
Console.WriteLine(primeraCausaDeFila?.Message.ToString()); // Nombre obligatorio.
Console.WriteLine(TreeTraversal.Children(error).Count); // 2.El primer bucle imprime la raíz, la fila, el nombre, el correo y el archivo, en ese orden. El recorrido visita cada nodo antes de descender por sus hijos y respeta el orden de Reasons. error.Reasons y Children(error) solo muestran el nivel inmediato.
Rutas hasta las hojas
csharp
foreach (var ruta in traversal.EnumerateLeafPaths(error))
Console.WriteLine(string.Join(" → ", ruta.Select(nodo => (string)nodo.Message)));text
Importación fallida. → Fila inválida. → Nombre obligatorio.
Importación fallida. → Fila inválida. → Correo inválido.
Importación fallida. → Archivo incompleto.Cada ruta es una lista independiente de solo lectura con referencias a los nodos originales. Una raíz sin hijos produce una ruta de un elemento. Puedes pasar fila para obtener rutas que comiencen en esa razón.
Las enumeraciones son diferidas. Siguen Reasons, no Parent, y conservan apariciones compartidas por distintas rutas. El recorrido corta repeticiones de un nodo en la misma rama para evitar ciclos; esto no equivale a deduplicar globalmente el árbol.
Subir al padre y a la raíz propietaria
csharp
INode padre = fila.Up();
Error raiz = fila.Root();
Console.WriteLine(ReferenceEquals(padre, error)); // True.
Console.WriteLine(ReferenceEquals(raiz, error)); // True.Up() devuelve el padre inmediato: INode en una razón dinámica, o TParent en una razón tipada. Lanza InvalidOperationException si no hay padre.
Root() se ofrece sobre IReasonNode y sigue Parent hasta un Error. Lanza InvalidOperationException si no llega a un error.
Una referencia no cambia la pertenencia. Por eso, al recorrer un error agregado o un error que referencia una razón, Root() puede devolver la raíz original y no el error desde el que iniciaste el recorrido. Usa EnumerateLeafPaths para conservar el contexto de la consulta. Consulta referencias de errores.
Sustitución de TreeQuery
La API actual no contiene TreeQuery. Sobre un error usa error.FindReason<T>(), HasReason<T>() o TryGetReason<T>(). Sobre una razón usa EnumerateDescendants con LINQ, como en el ejemplo de la fila.