类型成员的表达式导致不同的表达式(MemberExpression、UnaryExpression) [英] Expression for Type members results in different Expressions (MemberExpression, UnaryExpression)

查看:55
本文介绍了类型成员的表达式导致不同的表达式(MemberExpression、UnaryExpression)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表达式来指向我的类型的属性.但它不适用于每种属性类型.不意味着"是什么意思它导致不同的表达类型.我以为它会导致MemberExpression 但事实并非如此.

I have a expression to point on a property of my type. But it does not work for every property type. "Does not mean" means it result in different expression types. I thought it will ever result in a MemberExpression but this is not the case.

对于 intGuid 它导致 UnaryExpressionstringMemberExpression 中.

For int and Guid it results in a UnaryExpression and for string in a MemberExpression.

我有点困惑;)

我的班级

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

测试代码

Person p = new Person { Age = 16, Name = "John" };

Expression<Func<Person, object>> expression1 = x => x.Age;
// expression1.Body = UnaryExpression;

Expression<Func<Person, object>> expression2 = x => x.Name;
// expression2.Body = MemberExpression;

问题

我如何比较两个表达式并检查它们是否是平均的相同的类型和相同的属性?

Question

How can i compare two expressions and check if they are mean the same type and same property ?

感谢用户 dasblinkenlight 让我走上正轨.

Thanks to user dasblinkenlight who brought me on the right track.

他提供了方法

private static MemberExpression GetMemberExpression<T>(
    Expression<Func<T,object>> exp
) {
    var member = expr.Body as MemberExpression;
    var unary = expr.Body as UnaryExpression;
    return member ?? (unary != null ? unary.Operand as MemberExpression : null);
}

我写了下面的扩展方法来比较GetMemberExpression的结果方法并检查 GetMemberExpression().Member.Name 是否相同.

I wrote the following extension method to compare the results of the GetMemberExpression methods and check if GetMemberExpression().Member.Name are the same.

private static bool IsSameMember<T>(this Expression<Func<T, object>> expr1, Expression<Func<T, object>> expr2)
{
    var result1 = GetMemberExpression(expr1);
    var result2 = GetMemberExpression(expr2);

    if (result1 == null || result2 == null)
       return false;

    return result1.Member.Name == result2.Member.Name;
}

推荐答案

发生这种情况的原因是 Agevalue 类型.为了将返回值类型的表达式强制转换为 Func,编译器需要插入一个 Convert(expr, typeof(object)), a UnaryExpression.

The reason this happens is that Age is a value type. In order to coerce an expression returning a value type into Func<Person,object> the compiler needs to insert a Convert(expr, typeof(object)), a UnaryExpression.

对于strings和其他引用类型,则不需要装箱,因此返回一个直"的成员表达式.

For strings and other reference types, however, there is no need to box, so a "straight" member expression is returned.

如果你想得到UnaryExpression里面的MemberExpression,你可以得到它的操作数:

If you would like to get to the MemberExpression inside the UnaryExpression, you can get its operand:

private static MemberExpression GetMemberExpression<T>(
    Expression<Func<T,object>> exp
) {
    var member = exp.Body as MemberExpression;
    var unary = exp.Body as UnaryExpression;
    return member ?? (unary != null ? unary.Operand as MemberExpression : null);
}

这篇关于类型成员的表达式导致不同的表达式(MemberExpression、UnaryExpression)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆