Cuando se desea enumerar de forma recursiva un objeto jerárquico, seleccionando algunos elementos en función de algunos criterios, existen numerosos ejemplos de técnicas como el "aplanamiento" y luego filtrar utilizando LINQ: al igual que las que se encuentran aquí:¿Enumeración de colecciones que no son inherentemente IEnumerable?
Pero cuando enumera algo como la colección Controls de un Formulario, o la colección Nodos de un TreeView, no he podido utilizar este tipo de técnicas porque parecen requerir un argumento (al método de extensión) que es un IEnumerable colección: pasar en SomeForm.Controls no se compila.
Lo más útil que encontré fue esto:
¿Qué te da un método de extensión para Control.ControlCollection con un resultado IEnumerable luego se puede utilizar con LINQ.
Modifiqué el ejemplo anterior para analizar los Nodos de un TreeView sin ningún problema.
public static IEnumerable<TreeNode> GetNodesRecursively(this TreeNodeCollection nodeCollection)
{
foreach (TreeNode theNode in nodeCollection)
{
yield return theNode;
if (theNode.Nodes.Count > 0)
{
foreach (TreeNode subNode in theNode.Nodes.GetNodesRecursively())
{
yield return subNode;
}
}
}
}
Este es el tipo de código que estoy escribiendo ahora utilizando el método de extensión:
var theNodes = treeView1.Nodes.GetNodesRecursively();
var filteredNodes =
(
from n in theNodes
where n.Text.Contains("1")
select n
).ToList();
Y yo creo que puede ser una manera más elegante de hacer esto, donde la restricción (s) son pasado.
Lo que quiero saber si es posible definir tales procedimientos genéricamente, de modo que: en tiempo de ejecución puedo pasar el tipo de colección, así como la colección real, a un parámetro genérico, por lo que el código es independiente de si se trata de un TreeNodeCollection o Controls.Collection .
También me interesaría saber si hay alguna otra forma (¿más barata? Fastser?) Que la que se muestra en el segundo enlace (arriba) para obtener TreeNodeCollection o Control.ControlCollection en un formato que pueda utilizar Linq.
Un comentario de Leppie sobre 'SelectMany en la publicación SO vinculado al primero (arriba) parece una pista.
Mis experimentos con SelectMany han sido: bueno, llámelos "desastres". :)
Aprecie cualquier punteros. He pasado varias horas leyendo cada publicación SO que pude encontrar que tocaba en estas áreas, y adentrándome en un exotismo como el "y-combinator". Una experiencia "humillante", debo añadir :)
En "selector (elemento) .OfTipo()" OfType no es obligatorio, ya que debería devolver T. –
No, es obligatorio porque el selector devuelve IEnumerable y not e IEnumerable. –
mrydengren
Oh, veo el problema ahora. Actualicé el código para reflejar los cambios. Buena atrapada. – mrydengren