防爆pression的类型成员产生不同的防爆pressions(MemberEx pression,UnaryEx pression) [英] Expression for Type members results in different Expressions (MemberExpression, UnaryExpression)

查看:161
本文介绍了防爆pression的类型成员产生不同的防爆pressions(MemberEx pression,UnaryEx pression)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说明

我有一个EX pression指向我的类型的属性。 但它并不适用于每个属性类型的工作。 并不意味着手段 这导致不同的EX pression类型。我觉得它永远不会导致 MemberEx pression ,但事实并非如此。

有关 INT 的Guid 这会导致一个 UnaryEx pression 字符串 MemberEx pression

我有点糊涂;)

部分样品code

我的类

 公共类Person
{
    公共字符串名称{;组; }
    公众诠释年龄{获得;组; }
}
 

测试code

 者P =新的Person {年龄= 16,名称=约翰};

防爆pression< Func键<人,对象>> EX pression1 = X => x.Age;
// EX pression1.Body = UnaryEx pression;

防爆pression< Func键<人,对象>> EX pression2 = X => x.Name;
// EX pression2.Body = MemberEx pression;
 

问题

如何比较两个EX pressions,并检查他们的平均 相同类型和相同的属性?

更新,接听和完整的示例

由于用户的 dasblinkenlight 谁把我在正确的轨道上。

他提供的方法

 私有静态MemberEx pression GetMemberEx pression< T>(
    防爆pression< Func键< T,对象>> EXP
){
    VAR成员= expr.Body为MemberEx pression;
    VAR一元= expr.Body为UnaryEx pression;
    返回成员? (一元= NULL unary.Operand为MemberEx pression:!?NULL);
}
 

我写了下面的扩展方法来比较的结果 GetMemberEx pression 方法和检查 GetMemberEx pression()。Member.Name 是相同的。

 私有静态布尔IsSameMember< T>(此例pression< Func键< T,对象>>表达式1,防爆pression< Func键< T,对象>&GT ;表达式2)
{
    VAR RESULT1 = GetMemberEx pression(表达式1);
    VAR结果2 = GetMemberEx pression(表达式2);

    如果(RESULT1 == NULL || RESULT2 == NULL)
       返回false;

    返回result1.Member.Name == result2.Member.Name;
}
 

解决方案

出现这种情况的原因是,年龄的类型。为了强迫一个前pression返回值类型为 Func键&LT;人,对象&gt; 编译器需要插入的 转换(表达式的typeof(对象)) ,一个<一个href="http://msdn.microsoft.com/en-us/library/system.linq.ex$p$pssions.unaryex$p$pssion.aspx"><$c$c>UnaryEx$p$pssion.

有关字符串和其他引用类型,但也没有必要框,这样一个直当然成员pression返回。

如果你想获得的 MemberEx pression UnaryEx pression ,你可以得到它的操作:

 私有静态MemberEx pression GetMemberEx pression&LT; T&GT;(
    防爆pression&LT; Func键&LT; T,对象&gt;&GT; EXP
){
    VAR成员= expr.Body为MemberEx pression;
    VAR一元= expr.Body为UnaryEx pression;
    返回成员? (一元= NULL unary.Operand为MemberEx pression:!?NULL);
}
 

Description

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.

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

I am a little confused ;)

Some sample code

My class

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

Test Code

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 ?

Update, Answer and complete Sample

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

He provided the method

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

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

解决方案

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.

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

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 = expr.Body as MemberExpression;
    var unary = expr.Body as UnaryExpression;
    return member ?? (unary != null ? unary.Operand as MemberExpression : null);
}

这篇关于防爆pression的类型成员产生不同的防爆pressions(MemberEx pression,UnaryEx pression)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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