IEnumerable <timespan>的Sum方法扩展

时间:2015-11-01 13:41:55

标签: c# linq ienumerable extension-methods

编辑:很抱歉我的变量名称有些混乱。 TotalHours和Hours确实是TimeSpans,我试图总结TimeSpans,而不是Timespan的Hours属性。

我目前正在使用它来汇总表格中的“时间”列(TimeSpan类型):

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 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;
    }

我不熟悉funcs,扩展和泛型。我的错误是什么?如何才能使这项工作成功?

1 个答案:

答案 0 :(得分:3)

编辑感谢您澄清您想要实现的目标。我仍然不确定我是否真的得到它,所以这将是我最后一次尝试: - )

    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属性。我决定,您的意思是总结完整的实例 - 您可以从生成的TotalHours中访问所需的TimeSpan等信息。

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方法的结果。