C#在编译时生成返回类型未知的lambda表达式
本文关键字:未知 lambda 表达式 返回类型 编译 | 更新日期: 2023-09-27 18:29:29
假设我有以下方法:
public static String GetString(int a) {
return "";
}
public static int GetInt(int a) {
return 0;
}
现在,我想为其中一个方法创建一个lambda表达式,在编译时我只知道以下内容:
MethodInfo MethodInfo;上述方法之一的方法信息。
PropertyType属性类型;上述方法之一的返回类型的属性类型。
我不能在这里使用泛型类型,因为我不知道我希望在编译时调用哪个方法。
场景:
我有以下型号类别:
public class Model {
public String Name {
get;set;
}
public int Number {
get;set;
}
}
在运行时,我希望向这个模型注入信息。
public static void Inject<T>(T model) {
foreach(PropertyInfo propertyInfo in typeof(T).GetProperties()) {
Func<int, object> funcGet = GetValueFunc(propertyInfo.PropertyType);
propertyInfo.SetValue(model, funcGet.Invoke(0));
}
}
public static Func<int, object> GetValueFunc(Type propertyType) {
MethodInfo methodInfo = // say I know the method info here mapped to the propertyType
// this won't work since object isn't of either int or String
var iParam = Expression.Parameter(typeof(int), "iParam");
var call = Expression.Call(methodInfo, iParam);
var lambda = Expression.Lambda<Func<int, object>>(call, iParam);
return lambda.Compile();
}
真的有办法做到这一点吗?
我知道你可以做Expression.Convert(Expression.Parameter(typeof(object),"o"),propertyType);如果您在运行时不知道参数的类型。对于返回类型,有类似的方法吗?
好吧,您并没有完全强制转换"return type",因为您没有修改现有的方法代码。您需要转换该方法调用的结果,这是完全可行的,几乎可以使用您所说的:
var call = Expression.Call(methodInfo, iParam);
var cast = Expression.Convert(call, typeof (Object));
var lambda = Expression.Lambda<Func<int, Object>>(cast, iParam);
我认为这也解决了你的问题
public static Func<int, object> GetValueFunc(Type propertyType)
{
MethodInfo methodInfo = // say I know the method info here mapped to the propertyType
Func<int, object> result = (arg) => methodInfo.Invoke(null, new object[] {arg});
return result;
}