当泛型类型是对象时,如何在表达式中找到属性的类型?

时间:2011-07-31 23:35:18

标签: c# linq reflection expression-trees

我有一个linq表达式,用于将属性传递给需要它的方法。 但是直到运行时我才知道属性的类型。我需要能够找到表达式所代表的参数的原始类型,但它始终显示在{{1} }。

我有以下示例类:

System.Object

我有以下表达式,其中第二个泛型类型为public class SomeClass { public int SomeProp { get; set; } }

System.Object

我需要能够通过以下测试:

Expression<Func<SomeClass, object>> expression = x => x.SomeProp;

我意识到问题的根源在于我的表达式将public void PropertyShouldBeInt() { Expression<Func<SomeClass, object>> expression = x => x.SomeProp; Assert.AreEqual(expression.Body.Type, typeof(int)); } 指定为属性类型。但我正在通过一个object财产。我觉得我应该能够找到传递给表达式的属性的实际类型似乎是合理的。以下面的测试为例:

int

我觉得我应该能够引用public void AnObjectShouldKnowThatItIsAlsoSomethingElse() { object someObject = new SomeClass(); Assert.IsInstanceOfType(someObject, typeof (SomeClass)); } 类型并比较属性以找到原始类型。您对如何做到这一点的建议将不胜感激。或者,如果你有更好的方法,我会全力以赴。

编辑(找到解决方案后):

在下面的优秀答案之后,我想我会发布测试的工作版本以防其他人遇到同样的问题:

SomeClass

2 个答案:

答案 0 :(得分:3)

Expression<Func<SomeClass, object>> expression = x => x.SomeProp;
PropertyShouldBe<int>(expression);

// ...

public void PropertyShouldBe<T>(Expression<Func<SomeClass, object>> expr)
{
    // error-checking etc removed for brevity

    MemberExpression me;
    switch (expr.Body.NodeType)
    {
        case ExpressionType.Convert:
        case ExpressionType.ConvertChecked:
            var ue = expr.Body as UnaryExpression;
            me = ((ue != null) ? ue.Operand : null) as MemberExpression;
            break;
        default:
            me = expr.Body as MemberExpression;
            break;
    }

    Assert.AreEqual(me.Type, typeof(T));
}

答案 1 :(得分:-1)

它显示为object,因为您说它应该是object

Expression<Func<SomeClass, object>>

如果您希望它为int,则应为

Expression<Func<SomeClass, int>>

我想要了解的是,您传递的内容明确表明自己属于object类型typeof,然后问为什么它没有给您int 。也许这就足够了?

Assert.AreEqual(expression().GetType(), typeof(int))