Vous pouvez le faire avec une fonction d'ordre supérieur:
Func<Node, decimal> summer = null;
summer = node => node.Amount +
(node.Children == null ? 0m : node.Children.Sum(summer));
decimal total = summer(amounts);
Notez que si vous pouvez vous assurer que node.Children ne sera jamais nulle, l'été peut être plus simple:
summer = node => node.Amount + node.Children.Sum(summer);
Alternativement, vous pouvez utiliser l'opérateur de coalescence null:
summer = node => node.Amount +
(node.Children ?? Enumerable.Empty<Node>()).Sum(summer);
Bien sûr, vous pourriez mettre cela dans un autre méthode à la place:
static decimal SumNodes(Node node)
{
return node.Amount +
(node.Children ?? Enumerable.Empty<Node>())
.Sum((Func<Node, decimal>)SumNodes);
}
Notez que la laideur est due à une ambiguïté dans les conversions de groupes de méthodes. Les groupes de méthodes n'ont pas beaucoup d'amour dans l'inférence de type.
puis d'appeler SumNodes(amount)
. Beaucoup d'options :)
Exemple complet de la première forme:
using System;
using System.Collections.Generic;
using System.Linq;
class Node
{
public decimal Amount;
public IEnumerable<Node> Children { get; set; }
}
public class Test
{
static void Main()
{
var amounts = new Node {
Amount = 10, Children = new[] {
new Node { Amount = 20 },
new Node { Amount = 30 }
}
};
Func<Node, decimal> summer = null;
summer = node => node.Amount +
(node.Children == null ? 0m : node.Children.Sum(summer));
decimal total = summer(amounts);
Console.WriteLine(total);
}
}
Je ne suis pas sûr que je dirais l'un de ces un « simple » requête LINQ, vous l'esprit ...
Jon, je l'avouerais encore quelques fois, mais je ne le laisserai pas. –
Strictement, c'est plus d'une "fonction d'ordre supérieur" que d'un vrai "lambda récursif" ... –
Ce n'était pas juste jusqu'à ce que je l'ai réparé :) –