You can do this with a higher order function:
Func<Node, decimal> summer = null; summer = node => node.Amount + (node.Children == null ? 0m : node.Children.Sum(summer)); decimal total = summer(amounts);
Please note that if you can guarantee that node. Children will never be empty, summer can be easier:
summer = node => node.Amount + node.Children.Sum(summer);
Alternatively, you can use the null coalescing operator:
summer = node => node.Amount + (node.Children ?? Enumerable.Empty<Node>()).Sum(summer);
Of course, you can put this in a separate method:
static decimal SumNodes(Node node) { return node.Amount + (node.Children ?? Enumerable.Empty<Node>()) .Sum((Func<Node, decimal>)SumNodes); }
Note that the ugliness here is due to the ambiguity in transforming groups of methods. Method groups are not very fond of output type.
and then call SumNodes(amount) . Lots of options :)
Full example of the first form:
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); } }
I'm not sure what I would call any of these "simple" LINQ queries, mind you ...
source share