l33*_*33t 3 c# lambda expression-trees
我有一个LambdaExpression类型为Expression<Func<T, string>>. 代码的设计目前不允许我保留T,这意味着我被迫使用较慢的DynamicInvoke而不是Invoke.
因为我知道T我想要转换表达式的类型,以便它接受一个T对象,允许我使用Invoke. 如何?
这是一个好的开始
class Program
{
class MyClass
{
public string MyProperty => "Foo";
}
static LambdaExpression GetExpression(Expression<Func<MyClass, object>> expr)
{
return expr;
}
static void Main(string[] args)
{
var e1 = GetExpression(t => t.MyProperty);
var e2 = Expression.Lambda<Func<object, object>>(e1, e1.Parameters);
object myClass = new MyClass();
string s1 = (string)e1.Compile().DynamicInvoke(myClass);
object s2 = e2.Compile().Invoke(myClass);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
非表达式版本看起来像
Func<object, object> Convert<T>(Func<T, object> f) {
return o => f((T)o);
}
Run Code Online (Sandbox Code Playgroud)
这也是您在表达式版本中需要执行的操作。你说得对,Expression.Convert可以做到。
Expression<Func<MyClass, object>> e1 = t => t.MyProperty;
var p = Expression.Parameter(typeof(object));
var e2 = Expression.Lambda<Func<object, object>>(
Expression.Invoke(e1, Expression.Convert(p, typeof(MyClass))), p);
Run Code Online (Sandbox Code Playgroud)
注意:正如@xanatos 正确指出的那样,对于转换 egExpression<Func<T, int>>到Expression<Func<object, object>>,尽管 C# 支持从intto的隐式装箱转换object,但表达式树不支持。如果这与问题有关,Expression.Convert则需要另一个。