2014-06-23 52 views
0

我有一個這樣的對象:使用LINQ to選擇物業使用表達式

public class Sheet 
{ 
    public decimal? Value1 { get; set; } 
    public decimal? Value2 { get; set; } 
} 

我有一個LINQ查詢構建的Tuple<int, Sheet>列表。 int是存儲在我們數據庫中的百分比值。這可能是一個包裝類,但爲了簡單起見,我使用了一個Tuple。

然後,我有一個擴展方法

public static decimal CalculateValue(this List<Tuple<int, Sheet>> sheets, Expression<Func<Tuple<int, Sheet>, decimal?>> field) 
{ 
    //return sum of int/100 * field 
} 

我想要做的就是通話這樣的事情(列表使用LINQ的對象實際上是建立)

List<Tuple<int, Sheet>> sheets = new List<Tuple<int, Sheet>>(); 

var value1 = sheets.CalculateValue(x => x.Value1); 
var value2 = sheets.CalculateValue(x => x.Value2); 

我不想使用反射。我不想要「魔術」字符串的屬性Value1Value2。是否有一種方法讓我的擴展方法使用表達式獲取屬性,然後將其乘以百分比,然後在整個集合中對結果進行求和?

+1

爲什麼你使用表達式而不是簡單的Func? –

回答

1

根據您試圖構建的API,您應該爲Sheet對象傳遞屬性選擇器,而不是Tuple<int, Sheet>。您也可以使用簡單的Func委託而不是表達式,因爲您正在處理內存中的對象。

目前尚不清楚你將如何處理空值 - 這絕對是沒有意義的空倍增,所以我只是用零而不是空的(這樣的值不會影響總和):

public static decimal CalculateValue(
    this List<Tuple<int, Sheet>> sheets, Func<Sheet, decimal?> field) 
{ 
    return sheets.Sum(t => t.Item1 * field(t.Item2).GetValueOrDefault()/100); 
} 

請記住 - 當您將分割運算符應用於兩個整數時,將使用integer division。如果Item1的值小於100,則該部門將生成0。這就是爲什麼我把乘法運算符放在第一位。