2016-09-27 26 views
1

我有這些方法,你可能會認爲我也可能有其他數字類型。有什麼方法可以將這些方法合併爲一個通用方法?如何在此處使用通用方法?

public long GetActiveDepartmentsQuotaOf (Func<Department, long> exp) 
{ 
    return Departments == null ? 0 : Departments.Where(d => d.Status == 1).Sum(exp); 
} 

public int GetActiveDepartmentsQuotaOf (Func<Department, int> exp) 
{ 
    return Departments == null ? 0 : Departments.Where(d => d.Status == 1).Sum(exp); 
} 

我嘗試這樣做:

public T GetActiveDepartmentsQuotaOf<T> (Func<Department, T> exp) 
{ 
    return Departments == null ? 0 : Departments.Where(d => d.Status == 1).Sum(exp); 
} 

但語法錯誤。有什麼辦法擺脫這種情況?我只是好奇

+2

它只是一個錯字,或者您嘗試將'T'從'TGetActiveDepartmentsQuotaOf'分開嗎? –

+0

['Sum()'本身是通過多重載實現的](https://msdn.microsoft.com/en-us/library/bb548890(v = vs.110).aspx),就像前兩種方法一樣。沒有可用於約束'T'的'可編輯的'或'IAddable '接口(類似於'IEquatiable '),並且您不能說'where T:int或T:long或T:double' 。你不能從這裏到達那裏(除了一些醜陋的東西)。我不止一次希望我能。 –

回答

3

這是行不通的,因爲Enumerable.Sum方法僅適用於某些類型的可歸納(例如intdoublefloat)的IEnumerables。

以下是完整的重載列表:https://msdn.microsoft.com/en-us/library/system.linq.enumerable.sum(v=vs.110).aspx

目前還不清楚你如何總結的IEnumerable<T>,其中T可以是任何東西。想象一下,例如,TDepartment。你會期望.Sum()在那種情況下返回?

+0

所以我在尋找像@Mong Zhu's的答案。限制使用某些類型的條件。但它仍然會給出同樣的錯誤。因此,我沒有太多選擇,要麼使用許多方法,要麼按照romain-aga的建議接受轉換。 –

1

這是否適合您?

public T GetActiveDepartmentsQuotaOf<T>(Func<Department, double> exp) 
    where T : IConvertible 
{ 
    return (T)Convert.ChangeType(Departments == null 
     ? 0 : Departments.Where(d => d.Status == 1).Sum(exp), typeof(T)); 
} 

編輯:見末

但你必須轉換爲int(或兩次,如果你能有一些十進制數)的拉姆達(或方法)的返回值。


編輯

如果你真的需要Func<Department, T>簽名:

public T GetActiveDepartmentsQuotaOf<T>(Func<Department, T> exp) 
    where T : IConvertible 
{ 
    return (T)Convert.ChangeType(Departments == null 
      ? 0 
      : Departments.Where(d => d.Status == 1) 
       .Sum(d => (int)Convert.ChangeType(exp(d), typeof(double))) 
     , typeof(T)); 
} 

編輯:我改變從int類型在我的解決方案翻番(由於@ Servy的評論),以確保沒有人會因支持十進制的更改而感到困惑。至少現在,整數和小數也可以。 你也應該知道,使用小數時可能會導致精度損失(但我想只有很長的小數部分會受到影響)。

+0

這不會計算非整數值的正確總和,更糟糕的是,它沒有提供任何指示;這個簽名意味着它將適當地總結任何可轉換類型,即使它不能。 – Servy

+0

這就是爲什麼我說如果他需要計算一些十進制數,他可以改爲double);但是,我知道我寫的解決方案不支持小數。既然你說了這個,我會換掉這些類型,至少不會有更多的混淆。 –

+0

您選擇哪一個並不重要,關鍵是您只能支持*一個*類型,而不是*全部*。如果您將其從使用整數總和更改爲雙倍總和,它將不適用於非雙重總和。如果您將其更改爲使用小數,那麼它將不適用於非小數和。您需要實際使用基於實際類型的總和來可靠地獲得正確的結果。 – Servy