【问题标题】:Passing expression into lambda将表达式传递给 lambda
【发布时间】:2013-08-14 10:58:56
【问题描述】:

我有这样的课:

public class SomeClass
{
    public string Text1 { get; set; }

    public string Text2 { get; set; }

    public int Number { get; set; }
}

我有这些类对象的列表:

List<SomeClass> myList = new List<SomeClass>();

我想使用 LINQ(lambda 语法)查询此列表:

var result = myList.Where(obj => obj.Text1 == "SomeString");

是否有任何方法可以传递属性(例如,通过字符串名称),我希望通过它来执行此 LINQ 查询?在此示例中,我按 Text1 属性进行搜索,但假设我想在 Text1 或 Text2(在运行时确定)上动态调用此搜索。我希望能够传递执行此搜索的属性名称,并检查此属性是否为字符串,以便我确定可以先执行此搜索。

这可能吗?我知道 Reflections 和 Expressions 与它有关,但我不太了解它们。

谢谢

【问题讨论】:

  • 您不能使用默认 linq 传递动态参数,但是您可以使用一些库来实现这一点。

标签: c# reflection lambda expression


【解决方案1】:

使用反射的方法:

var result = myList.Where(obj => obj.GetType()
                                    .GetProperty("Text1")
                                    .GetValue(obj)
                                    .Equals("SomeString"));

通过这种方式,您可以将"Text1" 属性更改为"Text2"

您可以使用的另一种方法dynamic linq

var result = myList.AsQueryable().Where("Text1=@0", "SomeString");

动态 LINQ 也可通过 nuget 获得。

【讨论】:

    【解决方案2】:

    你可以使用表达式树吗?

    string memberName = "Text1", value = "SomeString";
    var p = Expression.Parameter(typeof(SomeClass), "obj");
    var predicate = Expression.Lambda<Func<SomeClass, bool>>(
        Expression.Equal(
            Expression.PropertyOrField(p, memberName),
            Expression.Constant(value,typeof(string))
        ), p);
    var result = myList.AsQueryable().Where(predicate);
    

    或替代最后一行:

    var result = myList.Where(predicate.Compile());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多