2
我正在做一些使用反射的工作,並希望創建一個LambdaExpression,我可以針對List<T>
集合運行並與HashSet<int>
集合相交以找到任何匹配。編譯Lambda表達式時參數不在範圍中
我的問題是,T
沒有實現一個通用的基類或接口,因此類型和需求tp的反射以編程方式構建Lambda表達式。
I'f我知道我的類型,我wnat執行是:
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();
}
}
}
在此先感謝!
哇,你很快!我打算明天登錄,看看有沒有人回覆:) – mnield
那麼,那將是另一個ParameterExpression呢,對吧?確實,在最終版本中並不是一個常數。 – mnield
@mnield - 你已經有了參數表達式;你只是沒有把它包含在對'Lambda'的調用中。它應該是'Expression.Lambda(methodCall,objectListParam,idList)'(或其他方式);同樣,您需要傳入* actual *列表來調用:'.DynamicInvoke(entityList,idList)' –