C# 当泛型类型为object时,如何在表达式中找到属性的类型?
我有一个linq表达式,用于将属性传递给需要它的方法但在运行时之前我无法知道属性的类型。我需要能够找到表达式表示的参数的原始类型,但它总是显示在C# 当泛型类型为object时,如何在表达式中找到属性的类型?,c#,linq,reflection,expression-trees,C#,Linq,Reflection,Expression Trees,我有一个linq表达式,用于将属性传递给需要它的方法但在运行时之前我无法知道属性的类型。我需要能够找到表达式表示的参数的原始类型,但它总是显示在System.Object中 我有以下示例类: public class SomeClass { public int SomeProp { get; set; } } 我有下面的表达式,其中第二个泛型类型是System.Object: Expression<Func<SomeClass, object>> expres
System.Object
中
我有以下示例类:
public class SomeClass
{
public int SomeProp { get; set; }
}
我有下面的表达式,其中第二个泛型类型是System.Object
:
Expression<Func<SomeClass, object>> expression = x => x.SomeProp;
我觉得我应该能够引用SomeClass
类型并比较属性以找到原始类型。如果您能提出建议,我们将不胜感激。或者,如果你有更好的办法,我洗耳恭听
编辑(找到解决方案后):
在得到下面的优秀答案后,我想我应该发布我的测试的工作版本,以防其他人也有同样的问题:
public void PropertyShouldBeInt()
{
Expression<Func<SomeClass, object>> expression = x => x.SomeProp;
Assert.AreEqual(((UnaryExpression) expression.Body).Operand.Type, typeof (int));
}
public void属性shouldbeint()
{
Expression=x=>x.SomeProp;
AreEqual(((UnaryExpression)expression.Body).Operand.Type,typeof(int));
}
它显示为对象
,因为你说它应该是对象
Expression<Func<SomeClass, object>>
我试图理解的是,您正在向
typeof
传递一个明确声明自己是object
类型的东西,然后询问它为什么不给您int
。也许这就足够了
Assert.AreEqual(expression().GetType(), typeof(int))
Expression=x=>x.SomeProp;
属性应为(表达式);
// ...
公共无效属性应为(表达式表达式表达式)
{
//为简洁起见,删除了错误检查等
请原谅我;
开关(expr.Body.NodeType)
{
大小写表达式类型。转换:
case ExpressionType.ConvertChecked:
变量ue=将主体表示为一元表达式;
me=((ue!=null)?ue.Operand:null)作为MemberExpression;
打破
违约:
me=将主体表示为成员表达式;
打破
}
AreEqual(me.Type,typeof(T));
}
我需要表达式保持原样。相反,我需要能够找出财产的实际类型。如前所述,在运行时之前我无法知道属性的类型,因此我无法硬编码表达式以获取int。您本质上是在问“为什么typeof(object)
不是int
?”请参见我的编辑。即使一个对象是一个对象
,它仍然应该知道它是什么(int、string等)。我只是查看了UnaryExpression类型,看到了操作数属性。这正是我想要的。回答得很好。
Expression<Func<SomeClass, object>>
Expression<Func<SomeClass, int>>
Assert.AreEqual(expression().GetType(), 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));
}