2015-11-01 114 views
2

編輯:對於我的變量的名稱混淆抱歉。 TotalHours和Hours確實是TimeSpans,我正在總結TimeSpans,而不是Timespan的Hours屬性。IEnumerable的總和方法擴展<TimeSpan>

我目前使用這在我的表總結(類型爲時間跨度)的小時數列

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

我試圖做的點心擴展了IEnumerable這樣,但它不工作:

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

我搜索了.NET源代碼,並發現,現有的總和方法爲退貨:

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

我對功能,擴展和泛型不太熟悉。我的錯誤是什麼?我該如何做這項工作?

+0

請發佈[mcve]。你當前的代碼有幾個不相關的錯誤,大概是不存在於你的真實代碼中的。這使得很難分辨實際問題是什麼。 – hvd

+2

TotalHours = MainGridTable.Sum(x => x.Hours),如果您只是想將IEnumerable中的每個TimeSpan的值相加。你想要什麼超過時間總和 –

+0

@MrinalKamboj我認爲'小時'是'TimeSpan'類型的屬性,並且OP不加總'TimeSpan.Hours'屬性。或者我誤解了你的評論? – hvd

回答

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屬性。我決定,你的意思是總結完整的實例 - 你可以從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方法的結果。

+0

我添加了一個編輯來嘗試清除混淆。我確實在總結TimeSpans,而不是他們的Hours屬性。問題是我正嘗試創建一個可應用於任何IEnumerable的Sum擴展,並使用lambda選擇每個枚舉項的TimeSpan屬性,從而返回另一個TimeSpan。 感謝有關TimeSpans不變性的問題,這會讓我稍後頭疼。 – Rynvar

+0

感謝您的幫助,這有效。我也偶然發現了一個相關搜索的[這個答案](http://stackoverflow.com/a/13169939/3781436),我不敢相信我之前沒有找到。我只是無法弄清楚如何使用函數的選擇器參數。 – Rynvar

0

不知道如果我得到你的確切要求,但如果你想在IEnumerable添加各種Timespan,然後做這個,假設類型IEnumerable<TimeSpan>

double totalHours = TE.Sum(t=>t.TotalHours); 

TE現在創建一個結果TimeSpan作爲

TimeSpan result = TimeSpan.FromHours(totalHours); 

這將負責填充各種組件,如Days, hours, minutes, seconds內部,這裏它代表Total time in hours不僅是小時公司mponent

在問題因爲它似乎,MainGridTable DataTable可以含有TimeSpan列,其可以被提取以產生相關IEnumerable或假設DataTable中TSTimespan列,所以如下:

double totalHours = MainGridTable.AsEnumerable(row=>TimeSpan.Parse(row["TS"]) 
           . Sum(t=>t.TotalHours); 

作爲如上所示使用totalHours創建TimeSpan結果

相關問題