Expression lambda récursive pour parcourir un arbre en C #

Quelqu’un peut-il me montrer comment implémenter une expression lambda récursive pour parcourir une structure en C #.

Ok, j’ai enfin trouvé du temps libre.
Et c’est parti:

class TreeNode { public ssortingng Value { get; set;} public List Nodes { get; set;} public TreeNode() { Nodes = new List(); } } Action traverse = null; traverse = (n) => { Console.WriteLine(n.Value); n.Nodes.ForEach(traverse);}; var root = new TreeNode { Value = "Root" }; root.Nodes.Add(new TreeNode { Value = "ChildA"} ); root.Nodes[0].Nodes.Add(new TreeNode { Value = "ChildA1" }); root.Nodes[0].Nodes.Add(new TreeNode { Value = "ChildA2" }); root.Nodes.Add(new TreeNode { Value = "ChildB"} ); root.Nodes[1].Nodes.Add(new TreeNode { Value = "ChildB1" }); root.Nodes[1].Nodes.Add(new TreeNode { Value = "ChildB2" }); traverse(root); 

Une solution appropriée, voire la solution idiomatique dans de nombreux langages de programmation fonctionnels, consisterait à utiliser un combinateur à virgule fixe . En bref: un combinateur à virgule fixe répond à la question «comment définir une fonction anonyme pour qu’elle soit récursive?». Mais la solution est si simple que des articles entiers sont écrits pour les expliquer.

Une alternative simple et pragmatique consiste à «remonter dans le temps» aux ébats de C: déclaration avant définition. Essayez ce qui suit:

 Func fact = null; fact = x => (x == 0) ? 1 : x * fact(x - 1); 

Fonctionne comme un charme.

Une alternative simple consiste à «remonter dans le temps» aux ébats de C et de C ++: déclaration avant définition. Essayez ce qui suit:

 Func fact = null; fact = x => (x == 0) ? 1 : x * fact(x - 1); 

Fonctionne comme un charme.

Oui, ça marche, avec une petite mise en garde. C # a des références mutables. Donc, assurez-vous de ne pas faire accidentellement quelque chose comme ceci:

 Func fact = null; fact = x => (x == 0) ? 1 : x * fact(x - 1); // Make a new reference to the factorial function Func myFact = fact; // Use the new reference to calculate the factorial of 4 myFact(4); // returns 24 // Modify the old reference fact = x => x; // Again, use the new reference to calculate myFact(4); // returns 12 

Bien sûr, cet exemple est un peu artificiel, mais cela pourrait se produire lors de l’utilisation de références mutables. Si vous utilisez les combinateurs des liens d’ aku , cela ne sera pas possible.

En supposant un object mythique TreeItem, cela rassemble une collection Children pour représenter votre hiérarchie.

  public void HandleTreeItems(Action item, TreeItem parent) { if (parent.Children.Count > 0) { foreach (TreeItem ti in parent.Children) { HandleTreeItems(item, ti); } } item(parent); } 

Maintenant, appelez-le en transmettant le lambda qui gère un élément en imprimant son nom sur la console.

 HandleTreeItems(item => { Console.WriteLine(item.Name); }, TreeItemRoot);