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

发布于 2024-11-27 03:30:55 字数 1365 浏览 0 评论 0原文

我有一个 linq 表达式,旨在将属性传递给需要它的方法。 但是直到运行时我才能知道属性的类型。我需要能够找出表达式所表示的参数的原始类型,但它总是显示在System中.对象

我有以下示例类:

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 类型并比较属性以找到原始类型。如果您就如何做到这一点提出建议,我们将不胜感激。或者,如果你有更好的方法来做到这一点,我洗耳恭听。

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

在下面的出色回答之后,我想我应该发布测试的工作版本,以防其他人遇到同样的问题:

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

I have an linq expression that is meant to pass a property around to methods that need it. But I cannot know the type of the property until runtime. I need to be able to find out the original type of the parameter that is represented by the expression, but it always shows up at System.Object.

I have the following example class:

public class SomeClass
{
    public int SomeProp { get; set; }
}

I have the following expression where the 2nd generic type is System.Object:

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

I need to be able to pass the following test:

public void PropertyShouldBeInt()
{
    Expression<Func<SomeClass, object>> expression = x => x.SomeProp;
    Assert.AreEqual(expression.Body.Type, typeof(int));
}

I realize the problem is rooted in that my expression specifies object as the property type. But I'm passing in an int property. It seems reasonable to me that I should be able to find out the actual type of the property that has been passed to the expression. Take the following test for example:

public void AnObjectShouldKnowThatItIsAlsoSomethingElse()
{
    object someObject = new SomeClass();
    Assert.IsInstanceOfType(someObject, typeof (SomeClass));            
}

I feel like I should be able to reference the SomeClass type and compare the properties to find the original type. Your suggestions as to how to do that would be appreciated. OR, if you have a better way to do this, I'm all ears.

EDIT (after solution was found):

After the excellent answer below, I thought I'd post the working version of my test in case others have the same issue:

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

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

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

发布评论

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

评论(2

沦落红尘 2024-12-04 03:30:55
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));
}
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));
}
通知家属抬走 2024-12-04 03:30:55

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

Expression<Func<SomeClass, object>>

如果你希望它是 int,它应该是

Expression<Func<SomeClass, int>>

What I am试图理解的是,您正在将明确声明自己为 object 类型的内容传递给 typeof,然后询问为什么它不给您 int< /代码>。也许这就足够了?

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

It shows up as object because you say it should be object when you do

Expression<Func<SomeClass, object>>

If you want it to be int, it should be

Expression<Func<SomeClass, int>>

What I am trying to get across is that you are passing something that explicitly states itself to be of type object to typeof, then asking why it isn't giving you int. Maybe this would suffice?

Assert.AreEqual(expression().GetType(), typeof(int))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文