C#生成一个lambda表达式,其中返回类型在编译时是未知的

时间:2014-11-07 14:06:08

标签: c# lambda return compile-time

假设我有以下方法:

public static String GetString(int a) {
    return "";
}

public static int GetInt(int a) {
    return 0;
}

现在我想为其中一个方法创建一个lambda表达式,我只在编译时知道以下内容:

MethodInfo methodInfo;上述方法之一的方法信息。

PropertyType 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); 如果您不知道运行时参数的类型。是否有类似的方法为返回类型执行此操作?

2 个答案:

答案 0 :(得分:1)

嗯,由于您没有修改现有的方法代码,因此您并未完全转换&#39;返回类型&#39;。你需要转换该方法调用的结果,并且完全可行,几乎使用你所说的:

var call = Expression.Call(methodInfo, iParam);
var cast = Expression.Convert(call, typeof (Object));
var lambda = Expression.Lambda<Func<int, Object>>(cast, iParam);

答案 1 :(得分:0)

我认为这也解决了你的问题

    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;
    }