Quando si desidera elencare ricorsivamente un oggetto gerarchico, selezionando alcuni elementi sulla base di alcuni criteri, ci sono numerosi esempi di tecniche come "appiattimento" e quindi il filtraggio utilizzando Linq: come quelli trovati qui:Enumerazione di raccolte che non sono intrinsecamente IEnumerable?
Tuttavia, quando si enumera qualcosa come la raccolta Controls di un Form o la raccolta Nodes di un TreeView, non sono stato in grado di utilizzare questi tipi di tecniche perché sembrano richiedere un argomento (al metodo di estensione) che è un IEnumerable collezione: il passaggio in SomeForm.Controls non viene compilato.
La cosa più utile che ho trovato è stato questo:
che ti dà un metodo di estensione per Control.ControlCollection con un risultato IEnumerable è possibile utilizzare con LINQ.
Ho modificato l'esempio precedente per analizzare i nodi di un TreeView senza problemi.
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;
}
}
}
}
Questo è il tipo di codice che sto scrivendo ora utilizzando il metodo di estensione:
var theNodes = treeView1.Nodes.GetNodesRecursively();
var filteredNodes =
(
from n in theNodes
where n.Text.Contains("1")
select n
).ToList();
e penso che ci possa essere un più elegante modo per fare questo in cui il vincolo (s) sono passato.
Che cosa voglio sapere se è possibile definire genericamente tali procedure, in modo che: in fase di esecuzione posso passare il tipo di raccolta, così come la raccolta effettiva, ad un parametro generico, quindi il codice è indipendente dal fatto che si tratti di TreeNodeCollection o Controls.Collection .
Mi piacerebbe anche sapere se c'è altro modo (più economico? Fastser?) Di quello mostrato nel secondo link (sopra) per ottenere un TreeNodeCollection o Control.ControlCollection in una forma utilizzabile da Linq.
Un commento di Leppie su "SelectMany nel post SO collegato al primo (sopra) sembra un indizio.
I miei esperimenti con SelectMany sono stati: beh, chiamali "disastri". :)
Apprezzare qualsiasi suggerimento. Ho passato molte ore a leggere ogni post SO che ho potuto trovare toccato in queste aree, e vagare per la mia strada in una tale esotismo come "y-combinator". Un'esperienza "umiliante", potrei aggiungere :)
Nel "selettore (elemento) .OfType()" l'OfType non è obbligatorio, come dovrebbe già restituire T. –
No è obbligatorio perché il selettore restituisce un IEnumerable e non e IEnumerable. –
mrydengren
Oh, vedo il problema ora. Ho aggiornato il codice per riflettere le modifiche. Buona pesca. – mrydengren