Если вы хотите рекурсивно перечислить иерархический объект, выбрав некоторые элементы, основанные на некоторых критериях, существует множество примеров таких методов, как "сглаживание", а затем фильтрация с использованием Linq: например, найденные здесь:
Но когда вы перечисляете что-то вроде коллекции элементов управления Form или коллекции узлов 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.
Мне также интересно узнать, есть ли другой способ (более дешевый? fastser?), чем тот, который показан во второй ссылке (выше), чтобы получить TreeNodeCollection или Control.ControlCollection в форме, которую можно использовать Linq.
Комментарий Leppie о "SelectMany" в сообщении SO, связанном с первым (см. выше), похоже на подсказку.
Мои эксперименты с SelectMany были: ну, назовите их "бедствиями".:)
Цените любые указатели. Я потратил несколько часов на чтение каждого сообщения SO, которое я смог найти, касающегося этих областей, и пробрался в такую экзотику, как "y-combinator". "Смиряющий" опыт, я мог бы добавить:)