[英]Get actual return type from a Expression<Func<T, object>> instance
I have a method that accepts a Expression<Func<T, object>>
instance.我有一个接受
Expression<Func<T, object>>
实例的方法。 I want to get at the actual data type being returned by a specific expression instance, rather than object
.我想获取特定表达式实例返回的实际数据类型,而不是
object
。
I can get it to work for direct property references, so if I pass in the expression x => x.IntegerProperty
I can get a Type reference for an integer.我可以让它用于直接属性引用,所以如果我传入表达式
x => x.IntegerProperty
我可以获得一个整数的 Type 引用。 This approach requires converting it to a MemberExpression.这种方法需要将其转换为 MemberExpression。
However, I can't get it to work for arbitrary expressions.但是,我无法让它用于任意表达式。 For instance, if the expression is
x => x.IntegerProperty.ToString()
I want to get a Type reference for a string.例如,如果表达式是
x => x.IntegerProperty.ToString()
我想获得一个字符串的类型引用。 I can't compile this to a MemberExpression, and if I just .Compile()
it and check the return type I get "object".我无法将其编译为 MemberExpression,如果我只是
.Compile()
它并检查返回类型,我会得到“对象”。
How can I look at the specific expression instance and derive the actual return type?如何查看特定的表达式实例并得出实际的返回类型?
Something like this might do the trick.像这样的事情可能会奏效。 It probably doesn't cover every possibility, but it's a start.
它可能没有涵盖所有可能性,但这是一个开始。
public static Type GetObjectType<T>(Expression<Func<T, object>> expr)
{
if ((expr.Body.NodeType == ExpressionType.Convert) ||
(expr.Body.NodeType == ExpressionType.ConvertChecked))
{
var unary = expr.Body as UnaryExpression;
if (unary != null)
return unary.Operand.Type;
}
return expr.Body.Type;
}
While not impossible, this is particularly difficult.虽然并非不可能,但这是特别困难的。 It would require walking the expression tree and doing some potentially complex logic.
它需要遍历表达式树并执行一些潜在的复杂逻辑。 For example, what would you want to see if I passed in the following expression?
例如,如果我传入以下表达式,您想查看什么?
Func<bool, object> expr = switch => switch ? 1 : "False";
This method could either return an int
or a string
.此方法可以返回
int
或string
。
Now, you might be able to make more headway by offloading some of this logic on the compiler.现在,您可以通过在编译器上卸载某些逻辑来取得更大进展。 You could change your method parameter from
Func<T, object>
to Func<T, TReturn>
and use typeof(TReturn)
within the method to determine what the compiler decided the return type of the expression was.您可以将方法参数从
Func<T, object>
更改为Func<T, TReturn>
并在方法中使用typeof(TReturn)
来确定编译器决定表达式的返回类型是什么。
Of course, in the case of my example, you'll still be working against object
.当然,在我的例子中,你仍然会使用
object
。 But, your example of x => x.IntegerProperty.ToString()
will yield string
, which is what you're looking for.但是,您的
x => x.IntegerProperty.ToString()
示例将产生string
,这就是您要查找的内容。
Bit of a cheeky way (and it involves actually invoking the Func
), but you can do this:有点厚颜无耻的方式(它涉及实际调用
Func
),但您可以这样做:
using System;
class Program
{
static Func<T,object> MakeFunc<T>()
{
return x => 23;
}
static Type GetReturnType<T>(Func<T,object> f)
{
return f(default(T)).GetType();
}
static void Main(string[] args)
{
Type t = GetReturnType(MakeFunc<string>());
Console.WriteLine(t);
}
}
It's not guaranteed to work in all situations, I should add - particularly if the default(T)
isn't a valid parameter to the Func
.不能保证在所有情况下都能工作,我应该补充 - 特别是如果
default(T)
不是Func
的有效参数。 But it's a potential starting point at least.但这至少是一个潜在的起点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.