usar una tipo puede expresión expresiones español ejemplos delegado cómo convertir consulta aprender c# recursion lambda

una - Expresión lambda recursiva para atravesar un árbol en C#



no se puede convertir expresión lambda en el tipo delegado (4)

¿Puede alguien mostrarme cómo implementar una expresión lambda recursiva para atravesar una estructura de árbol en C #.


Una alternativa simple es "retroceder en el tiempo" a las travesuras de C y C ++: declaración antes de la definición. Pruebe lo siguiente:

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

Funciona de maravilla.

Sí, eso funciona, con una pequeña advertencia. C # tiene referencias mutables. Así que asegúrese de no hacer accidentalmente algo como esto:

Func<int, int> fact = null; fact = x => (x == 0) ? 1 : x * fact(x - 1); // Make a new reference to the factorial function Func<int, int> 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

Por supuesto, este ejemplo es un poco artificial, pero esto podría ocurrir al usar referencias mutables. Si usa los combinadores de los enlaces de aku , esto no será posible.


Asumiendo un objeto mítico TreeItem, que conatins una colección de niños para representar su jerarquía.

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

Ahora llamarlo, pasando el lambda que maneja un elemento, imprimiendo su nombre en la consola.

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


Ok, encontré algo de tiempo libre finalmente.
Aquí vamos:

class TreeNode { public string Value { get; set;} public List<TreeNode> Nodes { get; set;} public TreeNode() { Nodes = new List<TreeNode>(); } } Action<TreeNode> 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);


Una solución adecuada, y de hecho la solución idiomática en muchos lenguajes de programación funcionales, sería el uso de un combinador de punto fijo . En pocas palabras: un combinador de punto fijo responde a la pregunta "¿cómo puedo definir que una función anónima sea recursiva?". Pero la solución es tan trivial que se escriben artículos completos para explicarlos.

Una alternativa simple y pragmática es "retroceder en el tiempo" a las travesuras de C: declaración antes de la definición. Pruebe lo siguiente:

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

Funciona de maravilla.