嗨,我基本上需要一个具有以下签名的功能
Expression<Func<T, object>> GetPropertyLambda(string propertyName)
Run Code Online (Sandbox Code Playgroud)
我做了一些尝试但是当属性可以为空时问题
就出现了,就像这样
ParameterExpression param = Expression.Parameter(typeof(T), "arg");
Expression member = Expression.Property(param, propertyName);
//this next section does conver if the type is wrong however
// when we get to Expression.Lambda it throws
Type typeIfNullable = Nullable.GetUnderlyingType(member.Type);
if (typeIfNullable != null)
{
member = Expression.Convert(member, typeIfNullable);
}
return Expression.Lambda<Func<T, object>>(member, param);
Run Code Online (Sandbox Code Playgroud)
例外是
'System.Decimal'类型的表达式不能用于返回类型'System.Object'
我真的会想到一些想法以及为什么它不能按预期工作
谢谢
实际上我不认为问题与Nullable类型有关,而是与值类型有关.尝试使用类型为decimal(不Nullable<decimal>)的属性的方法:它将以相同的方式失败.
看看如何为值和引用类型生成表达式树(例如,使用LinqPad)
Expression<Func<T, object>> lambda = x => x.AString;(参考类型)
=>身体是MemberExpression
Expression<Func<T, object>> lambda = x => x.ADecimal;(值类型)
=>主体是UnaryExpression与NodeType = Convert和Type = typeof(object),其Operand是一个MemberExpression
我稍微修改了你的方法以考虑到这一点,它似乎工作正常:
ParameterExpression param = Expression.Parameter(typeof(T), "arg");
Expression member = Expression.Property(param, propertyName);
if (member.Type.IsValueType)
{
member = Expression.Convert(member, typeof(object));
}
return Expression.Lambda<Func<T, object>>(member, param);
Run Code Online (Sandbox Code Playgroud)