我正在做一些使用反射的工作,并希望创建一个LambdaExpression,我可以针对List<T>
集合运行并与HashSet<int>
集合相交以查找任何匹配项。
我的问题是T
没有实现公共基类或接口,因此对类型和需求的反思以编程方式构建Lambda表达式。
我知道我的类型,我要执行的是:
List<TestClass> entityList = GetOriginalList();
HashSet<int> idList = new HashSet<int>() { 1, 2, 3, 4 };
List<TestClass> filteredList = entityList.Where(o => idList.Contains(o.Id)).ToList();
我开始使用LambdaExpression
嘲笑一种方法来做到这一点,但我无法得到编译的东西,似乎无法弄清楚如何做它想要的东西(即输入变量为HashSet<int>
)。我的提出尝试在下面,有没有人有任何建议如何让LambdaExpression
编译,以及如何实际执行它在另一端获得List<myObject>
?
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
namespace PoCDynamicLambda
{
class Program
{
class TestClass
{
private int _id;
private string _value;
public int Id { get { return this._id; } set { this._id = value; } }
public string Value { get { return this._value; } set { this._value = value; } }
public TestClass(int id, string value)
{
this._id = id;
this._value = value;
}
}
static void Main(string[] args)
{
List<TestClass> entityList = new List<TestClass>()
{
new TestClass(1, "One"),
new TestClass(2, "Two"),
new TestClass(3, "Three")
};
HashSet<int> idList = new HashSet<int>() { 2, 3, 5 };
MethodInfo containsMethod = idList.GetType().GetMethod("Contains");
ParameterExpression idListParam = Expression.Parameter(idList.GetType(), "idList");
ParameterExpression objectListParam = Expression.Parameter(typeof(TestClass), "entityList");
PropertyInfo idProperty = typeof(TestClass).GetProperty("Id");
MemberExpression idMember = Expression.Property(objectListParam, idProperty);
MethodCallExpression methodCall = Expression.Call(idListParam, containsMethod, idMember);
LambdaExpression le = Expression.Lambda(methodCall, objectListParam);
Console.WriteLine(le); // returns {entityList => idList.Contains(entityList.Id)}
le.Compile(); // Error here
Console.WriteLine(le.Compile().DynamicInvoke(entityList));
Console.ReadLine();
}
}
}
提前致谢!
答案 0 :(得分:1)
您需要在idList
的调用中包含Expression.Lambda
,并在最终调用中提供参数(在您的示例中为DynamicInvoke
)。或者如果要将其修复为{2,3,5},请将idList
替换为Expression.Constant
。
请注意,如果您想获得性能,则需要使用 typed 调用,而不是DynamicInvoke
。