Если вы хотите рекурсивно перечислить иерархический объект, выбирая некоторые элементы на основе некоторых критериев, существует множество примеров таких методов, как «выравнивание» и последующая фильтрация с использованием Linq: например, те, что найдены здесь:
текст ссылки
Но когда вы перечисляете что-то вроде коллекции Controls формы или коллекции Nodes TreeView, я не смог использовать эти типы методов, потому что они, кажется, требуют аргумента (для метода расширения), который коллекция IEnumerable: передача в SomeForm.Controls не компилируется.
Самым полезным, что я нашел, было следующее:
текст ссылки
Что дает вам метод расширения для Control.ControlCollection с IEnumerable результатом, который вы затем можете использовать с Linq.
Я изменил приведенный выше пример, чтобы проанализировать узлы TreeView без проблем.
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;
}
}
}
}
Это код, который я пишу сейчас, используя метод расширения:
var theNodes = treeView1.Nodes.GetNodesRecursively();
var filteredNodes =
(
from n in theNodes
where n.Text.Contains("1")
select n
).ToList();
И я думаю, что может быть более элегантный способ сделать это, когда передаются ограничения.
Что я хочу знать, возможно ли определить такие процедуры общим образом, чтобы: во время выполнения я мог передать тип коллекции, а также фактическую коллекцию, универсальному параметру, поэтому код независимо от того, является ли это TreeNodeCollection или Controls.Collection.
Мне также было бы интересно узнать, есть ли другой способ (более дешевый? Более быстрый?), Чем тот, который показан во второй ссылке (выше), для получения TreeNodeCollection или Control.ControlCollection в форме, используемой Linq.
Комментарий Леппи о «SelectMany» в сообщении SO, связанном с первым (выше), выглядит как подсказка.
Мои эксперименты с SelectMany были: ну, назовите их "бедствия". :)
Цените любые указатели. Я потратил несколько часов, читая каждый SO-пост, который касался этих областей, и пробирался к такой экзотике, как «y-combinator». «Унизительный» опыт, я мог бы добавить:)