在LINQ中使用sum方法

8

我正在尝试对一个泛型集合中的值进行求和。我在我的其他代码中使用了完全相同的代码来执行此功能,但似乎对于 ulong 数据类型存在问题?

代码如下:

   Items.Sum(e => e.Value); 

出现以下错误:

Error 15:调用以下方法或属性时存在歧义:System.Linq.Enumerable.Sum<System.Collections.Generic.KeyValuePair<int,ulong>>(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<int,ulong>>, System.Func<System.Collections.Generic.KeyValuePair<int,ulong>,float>)System.Linq.Enumerable.Sum<System.Collections.Generic.KeyValuePair<int,ulong>>(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<int,ulong>>, System.Func<System.Collections.Generic.KeyValuePair<int,ulong>,decimal?>)

该错误可能是因为在代码中使用了重载方法,但编译器无法确定要使用哪个方法。需要检查代码并明确指定要使用的方法。
public class Teststuff : BaseContainer<int, ulong, ulong>
{
    public decimal CurrentTotal { get { return Items.Sum(e => e.Value); } }

    public override void Add(ulong item, int amount = 1)
    {
    }

    public override void Remove(ulong item, int amount = 1)
    {
    }
}

public abstract class BaseContainer<T, K, P>
{
    /// <summary>
    /// Pass in the owner of this container.
    /// </summary>
    public BaseContainer()
    {
        Items = new Dictionary<T, K>();
    }

    public BaseContainer()
    {
        Items = new Dictionary<T, K>();
    }

    public Dictionary<T, K> Items { get; private set; }
    public abstract void Add(P item, int amount = 1);
    public abstract void Remove(P item, int amount = 1);
}
2个回答

20

Sum() 没有返回 ulong 的重载,编译器无法确定调用哪个已有的重载。

你可以使用转换帮助它做出决定:

Items.Sum(e => (decimal)e.Value)

谢谢,我刚把所有的无符号长整型改成了十进制,计时器结束后我会接受这个答案。 - lakedoo
1
@lakedoo:请注意,如果您更改了“Value”的类型,则不需要进行转换。另外,您确定不想使用“long”吗? - SLaks
好的,没问题,我会选长整型,这样似乎没有任何问题。再次感谢! - lakedoo
@lakedoo 注意溢出问题。将“ulong”相加并期望得到“long”似乎很危险。 要么您的属性一开始就不应该是“ulong”(如果它们确实需要这种精度,则您的求和将失败),要么您应该编写一个处理“ulong”的扩展程序来处理“Sum”。 - Rob
@jb1t的答案是最好的答案。它更安全(无溢出异常)并且更高效,因为它避免了对列表中的每个项目进行转换。 - Kevin McKinley
这是我在这个问题上看到的最好的答案。它在控制器代码和视图中都运行良好。感谢您的提示。@SLaks - user4059321

9

关于Sum()不存在返回ulong的重载,这一点是正确的,编译器无法决定调用哪个已有的重载函数。然而,如果你强制将它转换为long,就可能遇到System.OverflowException: Arithmetic operation resulted in an overflow.的问题。

相反地,你可以创建一个扩展方法,像这样:

public static UInt64 Sum(this IEnumerable<UInt64> source)
{
    return source.Aggregate((x, y) => x + y);
}

这样你就不必担心强制转换了,而且它还使用本地数据类型加法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接