通过传递resultSelector函数或直接将Aggregate
结果值传递给函数来使用LINQ Aggregate
方法时,是否存在实际差异?
代码示例(有更好的方法可以做到这一点,但这很好地说明了问题):
var list = new string[] { "a", "b", "c" };
list.Aggregate(new StringBuilder(), (sb, s) => sb.AppendLine(s), sb => sb.ToString());
list.Aggregate(new StringBuilder(), (sb, s) => sb.AppendLine(s)).ToString();
最后,两个语句都返回相同的字符串。有没有代码可以用一种方式编写,但不能用另一种方式?
据我所知,没有区别。看看我的Edulinq实现,我已经在没有选择器的情况下实现了重载,只需用选择器调用重载,然后进行身份转换:
public static TAccumulate Aggregate<TSource, TAccumulate>(
this IEnumerable<TSource> source,
TAccumulate seed,
Func<TAccumulate, TSource, TAccumulate> func)
{
return source.Aggregate(seed, func, x => x);
}
反过来做是完全合理的,例如
public static TResult Aggregate<TSource, TAccumulate, TResult>(
this IEnumerable<TSource> source,
TAccumulate seed,
Func<TAccumulate, TSource, TAccumulate> func,
Func<TAccumulate, TResult> resultSelector)
{
var intermediate = source.Aggregate(seed, func);
return resultSelector(intermediate);
}
现在,仅仅因为它们是等效的并不意味着过载是无用的。例如,有时使用lambda表达式来表达结果选择器会更容易:
var result = list.Aggregate(..., ..., total => total < 0 ? total + 1
: total - 1);
您可以创建一个单独的方法(或仅创建一个Func<TArg, TResult>
)来完成此操作,但在某些情况下,您希望在一个方法调用中完成整个操作。
简而言之,在每种情况下,使用对您最方便的方法;据我所知,它们是等价的。