你可以这样做。你的语法有点不对劲。它看起来像这样:
double sum = Calculate<double>(someFoo, f => f.a);
int count = Calculate<int>(someFoo, f => 1 + f.Length);
该方法如下所示:
public T Calculate<T>(Foo foo, Func<Foo, T> calculator)
{
return calculator(foo);
}
但是,所有这些对于Foo
. 更有可能的是,someFoo
应该真的是someFoos
,即多个对象。此外,我猜您也希望能够指定聚合方法。
那会变成Calculate
这样:
public T Calculate<T>(IEnumerable<Foo> foo, Func<Foo, T> calculator,
Func<IEnumerable<T>, T> aggregate)
{
return aggregate(foo.Select(calculator));
}
用法:
List<Foo> someFoos = ...;
var sum = Calculate(someFoos, x => x.a, Enumerable.Sum)
var count = Calculate(someFoos, x => 1 + x.Length, Enumerable.Count)
为了使其全部递归,最简单的方法是使用一个方法将Foo
对象及其所有子对象作为平面列表返回:
public IEnumerable<Foo> Flatten(Foo foo)
{
yield return foo;
foreach(var child in foo.Children.SelectMany(Flatten))
yield return child;
}
使用此方法Calculate
会导致:
public T Calculate<T>(IEnumerable<Foo> foo, Func<Foo, T> calculator,
Func<IEnumerable<T>, T> aggregate)
{
return aggregate(Flatten(foo).Select(calculator));
}
说了这么多,写了这么多,我要问:为什么不直接使用普通的LINQ呢?
Flatten(foo).Select(f => f.a).Sum();
Flatten(foo).Select(f => 1 + f.Length).Count();