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
方法的结果。
编辑:对于我的变量名称的混淆,我们深表歉意。 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
方法的结果。