Enumerable.Aggregate <tsource>中InvalidOperationException的原因是什么?</tsource>

时间:2010-03-30 20:19:38

标签: .net linq

为什么只有一个重载会抛出此异常?

小更新:我理解框架开发人员做出了一个设计决策。问题是为什么做出这个决定,有相关的设计模式还是其他什么?因为如果我正在设计我会返回默认值(TSource)。这种方法有什么问题?

3 个答案:

答案 0 :(得分:4)

您所指的Aggregate<TSource>版本为Aggregate<TSource>(this IEnumerable<TSource> enumerable)

聚合的这种特殊重载是唯一一个不包含聚合操作的种子(读取起始值)的重载。当枚举不包含任何元素时,这会创建一个有趣的案例。该方法可以执行以下任一操作

  • 抛出异常提醒用户注意问题
  • 返回default(TSource)

图书馆的作者选择了第一个。为什么我没有特别知道,但很可能是因为它被视为含糊不清,最好是模糊不清而不是成功(可能是错误的)默默地

其他两个重载没有问题,因为它们具有可以返回的种子/初始值。

答案 1 :(得分:2)

其他两个重载提供初始种子值。使用种子值,即使源为空,聚合也可以返回。

答案 2 :(得分:1)

抛出异常的一个重载需要类型为IEnumerable<TSource>this)和Func<TSource, TSource, TSource>的参数。它从第一个值开始并从那里累积。如果没有第一个值(如果source为空),则该函数无法知道要返回的内容。

其他两个重载接受类型TAccumulate的参数作为种子。即使source在这种情况下为空,该函数也可以简单地返回种子值。


更新:您问为什么决定在空序列的情况下简单地使用default(T)。答案不是归结为任何特定的模式或已知的习惯用语,而是简单地归结为(在我看来)API设计方面的合理选择。 Aggregate的目的是让开发人员能够轻松地针对他们自己的特定于域的问题实现计算,而无需对这些计算的语义进行假设

如果在空序列的情况下使用default(T),则不会选择两个非常假设:

  • 这个计算应该在空序列的情况下产生有意义的结果;和
  • 此结果应为default(T)

作为第一个假设的一个微不足道的反例,假设我使用Aggregate来计算整数序列的mode。这应该给出序列中最常出现的值,因此零的结果将是假的(因为值0 永远不会出现在空序列中)。

作为 second 的反例,假设我采用正整数序列的倒数乘积:

Aggregate [1, 2, 3, ...] -> 1 * 1/2 * 1/3 * ...

在这种情况下,当序列更大时,结果实际上接近于零,因此默认值零将再次完全误导。