【问题标题】:Using Linq to select property using an expression使用 Linq 使用表达式选择属性
【发布时间】:2014-06-23 22:26:29
【问题描述】:

我有一个这样的对象:

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

我有一个构建Tuple<int, Sheet> 列表的 linq 查询。 int 是存储在我们数据库中的百分比值。这可能是一个包装类,但为简单起见,我使用的是元组。

那我有一个扩展方法

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 的“魔法”字符串。有没有办法让我的扩展方法使用表达式获取属性,然后将其乘以百分比,然后将结果汇总到集合中?

【问题讨论】:

  • 为什么你使用表达式而不是简单的 Func?

标签: c# linq


【解决方案1】:

根据您尝试构建的 API,您应该为 Sheet 对象传递属性选择器,而不是 Tuple&lt;int, Sheet&gt;。您也可以使用简单的Func 委托代替表达式,因为您正在使用内存中的对象。

目前尚不清楚您将如何处理 null 值 - 乘以 null 肯定没有意义,所以我只使用零而不是 null(这样的值不会影响 sum):

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 作为结果。这就是为什么我把乘法运算符放在第一位的原因。

【讨论】:

    猜你喜欢
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多