gpt4 book ai didi

c# - 编译 LambdaExpression 时参数不在范围内

转载 作者:太空宇宙 更新时间:2023-11-03 14:21:51 28 4
gpt4 key购买 nike

我正在使用反射做一些工作,并想创建一个可以针对 List<T> 运行的 LambdaExpression收集并与 HashSet<int> 相交集合以查找任何匹配项。

我的问题是T不实现公共(public)基类或接口(interface),因此对类型的反射(reflection)和要求以编程方式构建 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();
}

}
}

提前致谢!

最佳答案

您需要在对 Expression.Lambda 的调用中包含 idList,并在最终调用中提供一个参数(在您的示例中为 DynamicInvoke ).或者,如果它要固定在 {2,3,5},请将 idList 替换为 Expression.Constant

请注意,如果您想获得性能,您需要使用typed 调用,而不是DynamicInvoke

关于c# - 编译 LambdaExpression 时参数不在范围内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5123861/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com