あなたはこれを行うことができます。ただし、構文は少しずれています。次のようになります。
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);
}
ただし、これらすべてが の 1 つのインスタンスでは意味を成しません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();