IEnumerable<TimeSpan> 的 Sum 方法扩展

Sum method extension for IEnumerable<TimeSpan>

编辑:对于我的变量名称的混淆,我们深表歉意。 TotalHours 和 Hours 确实是 TimeSpans,我试图总结 TimeSpans,而不是 Timespan 的 Hours 属性。

我目前正在使用它来对 table 中的小时列(时间跨度类型)求和:

TotalHours = MainGridTable.Select(x => x.Hours).Aggregate((x,y) => x.Add(y));

我试过像这样对 IEnumerable 进行 Sum 扩展,但它不起作用:

public static TimeSpan Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, TimeSpan> selector) 
{            
    return source.Aggregate(((t1, t2) => t1.Add(t2));         
}

我搜索了 .NET 源代码,发现现有的 Sum 方法return编辑为:

return Enumerable.Sum(Enumerable.Select(source, selector));

然后我尝试像这样将我的非通用 Sum 扩展扩展到 Enumerable,但是它没有被上面的 return 语句识别,它只是一直要求一个小数参数。

    public static TimeSpan Sum(this IEnumerable<TimeSpan> source) {
        TimeSpan sum = new TimeSpan(0, 0, 0);
        foreach (TimeSpan v in source) {
            if (v != null) sum.add(v);
        }
        return sum;
    }

我不太精通函数、扩展和泛型。我的错误是什么?我怎样才能使它起作用?

编辑 感谢您阐明您要实现的目标。我仍然不确定我是否真的明白了,所以这将是我最后一次尝试:-)

    public static TimeSpan Sum<TSource>(this IEnumerable<TSource> source, 
         Func<TSource, TimeSpan> selector) 
    {
        var ts = new TimeSpan();
        return source.Aggregate(ts, (current, entry) => current + selector(entry));
    }

我不确定你试图通过 TotalHours 表示什么,因为很明显,多个时间跨度(可能包括小时、分钟、天、秒等)的总和表示为总计小时是另一回事,只是总结了一些时间跨度的 Hours 属性。我决定,你的意思是总结完整的实例 - 你可以从结果 TimeSpan.

中访问所需的 TotalHours 等信息

TimeSpan 是不可变的,就像 DateTime 一样,一个常见的陷阱是,您需要使用 Add 方法的结果。

public static TimeSpan Sum(this IEnumerable<TimeSpan> source) {
    TimeSpan sum = new TimeSpan(0, 0, 0);
    foreach (TimeSpan v in source) {
        sum = sum.Add(v);
    }
    return sum;
}

还要注意,TimeSpan 是一个值类型 (struct),因此永远不能被 null。所以在你的代码中检查 null 是多余的。

LINQ 版本看起来像这样:

    public static TimeSpan Sum(this IEnumerable<TimeSpan> source)
    {
        TimeSpan sum = new TimeSpan(0, 0, 0);
        return source.Aggregate(sum, (current, v) => current.Add(v));
    }

同样,您需要使用 Add 方法的结果。