C # Create lambda expression where return type is unknown at compile time

Let's say I have the following methods:

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

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

      

Now I want to create a lambda expression for one of these methods where at compile time I only know the following:

MethodInfo methodInfo; Method information for one of the above methods.

PropertyType propertyType; The type of the return type property of one of the above methods.

What I cannot use here is a generic type, since I don't know which method I want to call at compile time.

Scenario:

I have the following model class:

public class Model {
    public String Name {
        get;set;
    }

    public int Number {
        get;set;
    }
}

      

At runtime, I want to enter information into this model.

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

      

Is there a way to do this?

I know you can do Expression.Convert (Expression.Parameter (typeof (object), "o"), propertyType); unless you know the type of the parameter at runtime. Is there a similar way to do this for return types?

+3


source to share


2 answers


Well, you are definitely not throwing away the "return type" since you are not modifying the existing method code. You need to execute the result of that method call instead, and that is perfectly doable, pretty much using what you stated:



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

      

+1


source


I think this will also solve your problem



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

      

0


source







All Articles