从属性名称获取属性 lambda(其中属性类型可以为空)

发布于 2024-08-12 17:41:08 字数 817 浏览 1 评论 0 原文

您好,我基本上需要一个具有以下签名的函数,

Expression<Func<T, object>> GetPropertyLambda(string propertyName)

我已经做了一些尝试,但是当属性可为空时就会出现问题
它是这样的

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);

例外是

类型的表达 '系统.十进制' 不能用于返回类型 '系统.对象'

我真的很欣赏一些想法以及为什么它不能按预期工作

谢谢

Hi there I basically need a function with the following signature

Expression<Func<T, object>> GetPropertyLambda(string propertyName)

I have made a few attempts but the problem arise when the property is nullable
it goes something like this

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);

The Exception is

Expression of type
'System.Decimal'
cannot be used for return type
'System.Object'

I would really apreciate some ideas and also why this doesnt work as expected

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

≈。彩虹 2024-08-19 17:41:08

实际上我不认为这个问题与 Nullable 类型有任何关系,而是与值类型有关。尝试使用 decimal 类型的属性(不是 Nullable)的方法:它也会以同样的方式失败。

看一下如何为值和引用类型生成表达式树(例如使用 LinqPad)

  • Expression>> λ = x => x.AString;(引用类型)
    =>主体是一个 MemberExpression

  • Expression> 。 λ = x => x.ADecimal;(值类型)
    =>主体是一个带有 NodeType = ConvertType = typeof(object)UnaryExpression,其 OperandMemberExpression

我稍微修改了你的方法以考虑到这一点,它似乎工作正常:

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);

Actually I don't think the problem has anything to do with Nullable types, but rather with value types. Try your method with a property of type decimal (not Nullable<decimal>) : it will fail the same way.

Have a look at how expression trees are generated for value and reference types (using LinqPad for instance)

  • Expression<Func<T, object>> lambda = x => x.AString; (reference type)
    => The body is a MemberExpression

  • Expression<Func<T, object>> lambda = x => x.ADecimal; (value type)
    => The body is a UnaryExpression with NodeType = Convert and Type = typeof(object), and its Operand is a MemberExpression

I modified your method slightly to take that into account, and it seems to work fine :

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文