当我只有泛型类型和实例值时,如何手动构建表达式树

本文关键字:何手动 构建 表达式 泛型类型 实例 | 更新日期: 2023-09-27 18:16:39

我有一个像下面这样的通用类:

public class MyClass<T, TProperty>
{
     MyClass(Expression<Func<T, TProperty>> expression)
     {
     }
}

在我的例子中,我想使用Activator动态地创建该类的实例。所以我需要为构造函数创建一个表达式。我所拥有的是类型(System.Type)和对象(System.Object),我想要像下面这样:

Expression<Func<T, TProperty>> exp = x => someValue;

"someValue"被声明为对象,但它的实际类型肯定是TProperty。它是通过反射来解析的,所以这里的类型是object。

问题是类型T和TProperty将是泛型的,直到运行时我才知道类型,所以我不能将"someValue"转换为TProperty。我们有typeof(T) typeof(TProperty)和一个对象-,-

当我只有泛型类型和实例值时,如何手动构建表达式树

好的,我想我明白你的问题了。

给定示例输入:

Type typeOfT = typeof(int);
Type typeOfTProperty = typeof(string);
object someValue = "Test";

你想创建的代码相当于:

var myClassInstance = new MyClass<int, string>(t => "Test");

你可以这样做。

首先,创建表达式树:
var parameter = Expression.Parameter(typeOfT, "t");
var body = Expression.Constant(someValue, typeOfTProperty);
// Will automatically be an Expression<Func<T, TProperty>> without any extra effort.
var lambda = Expression.Lambda(body, parameter);

然后使用反射创建MyClass<T, TProperty>实例:

var myClassType = typeof(MyClass<,>).MakeGenericType(typeOfT, typeOfTProperty);
//  Make the MyClass<,> constructor public first...
var myClassInstance = Activator.CreateInstance(myClassType, lambda);