且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C#中的时间跨度总和

更新时间:2023-02-10 21:02:43

不幸的是,没有接受 IEnumerableSum 重载.此外,目前还没有为类型参数指定基于运算符的泛型约束的方法,因此即使 TimeSpan 是本机"可求和的,但泛型代码无法轻松获取这一事实.>

一种选择是,如您所说,总结一个等效于时间跨度的整数类型,然后再次将 那个 和转换为 TimeSpan.对此的理想属性是 TimeSpan.Ticks,准确地往返.但是根本没有必要更改类的属性类型;你可以项目:

var totalSpan = new TimeSpan(myCollection.Sum(r => r.TheDuration.Ticks));

或者,如果您想坚持使用 TimeSpan 的 + 运算符进行求和,则可以使用 Aggregate 运算符:

var totalSpan = myCollection.Aggregate(时间跨度.零,(sumSoFar, nextMyObject) =>sumSoFar + nextMyObject.TheDuration);

I have a collection of objects that include a TimeSpan variable:

MyObject
{ 
    TimeSpan TheDuration { get; set; }
}

I want to use LINQ to sum those times. Of course, (from r in MyCollection select r.TheDuration).Sum(); doesn't work!

I'm thinking of changing the datatype of TheDuration to an int and then summing it and converting the sum to a TimeSpan. That will be messy because each TheDuration in my collection is used in as a timespan somewhere else.

Any suggestion on this summation?

Unfortunately, there isn't a an overload of Sum that accepts an IEnumerable<TimeSpan>. Additionally, there's no current way of specifying operator-based generic constraints for type-parameters, so even though TimeSpan is "natively" summable, that fact can't be picked up easily by generic code.

One option would be to, as you say, sum up an integral-type equivalent to the timespan instead, and then turn that sum into a TimeSpan again. The ideal property for this is TimeSpan.Ticks, which round-trips accurately. But it's not necessary to change the property-type on your class at all; you can just project:

var totalSpan = new TimeSpan(myCollection.Sum(r => r.TheDuration.Ticks));

Alternatively, if you want to stick to the TimeSpan's + operator to do the summing, you can use the Aggregate operator:

var totalSpan = myCollection.Aggregate
                (TimeSpan.Zero, 
                (sumSoFar, nextMyObject) => sumSoFar + nextMyObject.TheDuration);