我正在使用反射进行一些工作,并想创建一个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();
}
}
}
提前致谢!
最佳答案
您需要在对idList
的调用中包括Expression.Lambda
,并在最终调用中提供一个参数(在您的示例中为DynamicInvoke
)。或者,如果要将其固定为{2,3,5},则将idList
替换为Expression.Constant
。
请注意,如果要获得性能,则需要使用类型化调用,而不是DynamicInvoke
。
关于c# - 编译LambdaExpression时参数不在范围内,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5123861/