使用泛型获取C#中数组的元素总和

Nik*_*hil 3 c# arrays generics

我想编写一个方法,它可以采用数值类型的任意数组,并返回startIndex和endIndex之间所有元素的总和.这就是我所拥有的:

private static T SumArrayRange<T>(T[] scores, int startIndex, int endIndex)
{
    T score = 0;
    for (int i = startIndex; i <= endIndex; i++)
    {
        score += scores[i];
    }
    return score;
}
Run Code Online (Sandbox Code Playgroud)

但编译因这两个错误而失败.

  • 无法将类型'int'隐式转换为'T'.
  • 运算符'+ ='不能应用于'T'和'T'类型的操作数

有什么方法可以强制T只是其中一种数字类型(长,双等)?或者他们是一个更优雅的解决方法?

Pav*_*aev 11

不,没有办法限制泛型类型参数来使用运算符,也没有很好的解决方法.适当的一个将是一个接口,如INumericIArithmetic与方法如Add,Subtract等,由所有基本类型,如实施intlong.MS Connect中有一项为期5年的功能请求,仍然处于活动状态.最新消息是:

不幸的是,我们不得不削减我们在.NET Framework 4.0中解决此问题的计划.

在那之前,你将被降级为:

  • 自己使用反射 - 凌乱而且非常慢
  • 使用任何将为您使用Reflection的现有包装器(例如Microsoft.VisualBasic.CompilerServices.Operators类,使用反射等方法AddObject,SubtractObject并为相应的运算符实现VB语义) - 易于使用,但仍然很慢
  • 您想要处理的硬编码类型(即不支持用户定义类型上的重载算术运算符),并使用巨大的if (x is int) ... else if (x is double) ...语句.


Jac*_*cob 7

另一种方法是使用已经可用的LINQ工具,而不是编写自己的工具.例如:

var mySum = myCollection.Skip(startIndex).Take(count).Sum();
Run Code Online (Sandbox Code Playgroud)

由于Sum扩展方法适用于所有内置数字类型,因此您不必担心编写自己的数字类型.当然,如果您的代码的"myCollection"变量已经是泛型集合类型,那么这将不起作用.