How to use lambda expression parameter in “sub” expression?

后端 未结 1 1452
没有蜡笔的小新
没有蜡笔的小新 2021-01-19 10:49

I\'d like to be able to build expressions like the following delegate:

Func createSomeType1 = (args) =>
{
    return new SomeType1         


        
相关标签:
1条回答
  • 2021-01-19 11:31

    I'm on iPod, so can't give a full example at the moment: but:

    • declare a param of type object[] (Expression.Param(typeof(object[]))) and store that in a variable
    • for each term from the array, use the array indexer to obtain an expression to the indexer, and "Convert" or "cast" (iPod again!) to cast it
    • use Expression.Invoke, passing the inner expression plus the indexer+cast you generated above

    I'll be happy to do a complete example later if you need (when I'm at a PC)


    Full example:

    Type[] types = new Type[] { typeof(int), typeof(float), typeof(string) };
    
    var constructorInfo = typeof(SomeType).GetConstructor(types);
    var parameters = types.Select((t,i) => Expression.Parameter(t, "p" + i)).ToArray();
    var someType1Exp = Expression.New(constructorInfo, parameters);
    var inner = Expression.Lambda(someType1Exp, parameters);
    
    var args = Expression.Parameter(typeof(object[]), "args");          
    var body = Expression.Invoke(inner,
        parameters.Select((p,i) => Expression.Convert(Expression.ArrayIndex(args, Expression.Constant(i)), p.Type)).ToArray());
    var outer = Expression.Lambda<Func<object[], object>>(body, args);
    var func = outer.Compile();
    
    object[] values = {1, 123.45F, "abc"};
    object obj = func(values);
    Console.WriteLine(obj);
    

    Or as a single expression:

    Type[] types = new Type[] { typeof(int), typeof(float), typeof(string) };   
    var constructorInfo = typeof(SomeType).GetConstructor(types);
    
    var args = Expression.Parameter(typeof(object[]), "args");          
    var body = Expression.New(constructorInfo,
        types.Select((t,i) => Expression.Convert(Expression.ArrayIndex(args, Expression.Constant(i)), t)).ToArray());
    var outer = Expression.Lambda<Func<object[], object>>(body, args);
    var func = outer.Compile();
    
    object[] values = {1, 123.45F, "abc"};
    object obj = func(values);
    Console.WriteLine(obj);
    
    0 讨论(0)
提交回复
热议问题