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



我有一个linq表达式,用于将属性传递给需要它的方法。但是我不能知道属性的类型,直到运行时。我需要能够找出由表达式表示的参数的原始类型,但它总是显示在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类型并比较属性以找到原始类型。如能提供建议,我将不胜感激。或者,如果你有更好的方法,我洗耳恭听。

EDIT(找到解决方案后):

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

public void PropertyShouldBeInt()
{
    Expression<Func<SomeClass, object>> expression = x => x.SomeProp;
    Assert.AreEqual(((UnaryExpression) expression.Body).Operand.Type, typeof (int));
}
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));
}

显示为object,因为你说它应该是object,当你这样做

Expression<Func<SomeClass, object>>

如果你想让它是int,它应该是

Expression<Func<SomeClass, int>>

我想要理解的是,你正在传递一些明确声明自己是object类型的typeof的东西,然后问为什么它不给你int。也许这样就够了?

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

相关内容

  • 没有找到相关文章

最新更新