动态lambda使用表达式构建器进行select
我正在尝试编写一个动态选择语句。 我有以下几点:
public class MainList
{
public string Prop1{ get; set; }
public string Prop2{ get; set; }
public string Prop3{ get; set; }
}
public class SearchObject
{
public string Prop1{ get; set; }
}
我想要建立如下的表达式
var newList = MainList.Select(n => new SearchObject { Prop1 = n.Prop1});
我正在使用的代码创建一个基于MainList的列表。 然后,我现在通过传递SearchObject类型和我想要填充的参数来创建选择表达式。 它一直运行到倒数第二行。
public void Start()
{
List<MainList> newList = new List<MainList>(); //This has a ton list objects
var result = newList.Select(CreateSelect<SearchObject>("Prop1"));
}
public static Func<MainList, T> CreateSelect<T>(string fields)
{
var par = Expression.Parameter(typeof(T), "n");
var newInstance= Expression.New(typeof(T));
var bindings = fields.Split(',').Select(o => o.Trim())
.Select(n => {
var p = typeof(T).GetProperty(n);
var original = Expression.Property(par, p);
return Expression.Bind(p, original);
}
);
var newT= Expression.MemberInit(newInstance, bindings);
var lambda = Expression.Lambda<Func<MainList, T>>(newT, par); //ERROR HAPPENS HERE
return lambda.Compile();
}
我得到的错误是:
附加信息:类型'WebApplication.SearchObject'的ParameterExpression不能用于'WebApplication.MainList'类型的委托参数
我不确定错误的含义以及如何解决问题。
第一个问题是,正如Jeroen van Langen所述,参数的类型必须是MainList
。
第二个问题是使用Expression.Bind
。 由于源和目标是不同的类型,因此不能使用同一个PropertyInfo
。 第一个参数必须是目标类型T
的PropertyInfo
,而第二个表达式来自源类型MainList
(对于具有指定属性名称的参数,在您的情况下, Expression.Property
)。
正确的实现是这样的:
public static Func<MainList, T> CreateSelect<T>(string fields)
{
var parameter = Expression.Parameter(typeof(MainList), "n");
var bindings = fields.Split(',')
.Select(name => name.Trim())
.Select(name => Expression.Bind(
typeof(T).GetProperty(name),
Expression.Property(parameter, name)
));
var newT = Expression.MemberInit(Expression.New(typeof(T)), bindings);
var lambda = Expression.Lambda<Func<MainList, T>>(newT, parameter);
return lambda.Compile();
}
ParameterExpression of type 'WebApplication.SearchObject' cannot be used for delegate parameter of type 'WebApplication.MainList'
的异常ParameterExpression of type 'WebApplication.SearchObject' cannot be used for delegate parameter of type 'WebApplication.MainList'
解释:
含义: ParameterExpression
类型typeof(T)
与Expression.Lambda Func<MainList, T>
- > MainList
之间存在不匹配
你的:
var par = Expression.Parameter(typeof(T), "n");
应该:
var par = Expression.Parameter(typeof(MainList), "n");
链接地址: http://www.djcxy.com/p/68301.html