How Do I Create an Expression> with Type Parameters from a Type Variable

后端 未结 3 1236
终归单人心
终归单人心 2021-01-02 08:43

I\'d like to write a statement like the following:

Expression> filter = x => true;

Except instead of

相关标签:
3条回答
  • 2021-01-02 09:16

    You cant pass the Type as ageneric parameter, this is not the idea of a generic, what you want is simply a parameter to a method for instance.

    0 讨论(0)
  • 2021-01-02 09:17

    You'll need to create an expression with a body set to the constant true and a parameter of the type of your type. There is an Expression to do each of these things:

    Type type = typeof(object);
    var lambda = Expression.Lambda(
        Expression.Constant(true), 
        Expression.Parameter(type, "parameter"));
    
    0 讨论(0)
  • 2021-01-02 09:21

    You need to create the appropriate delegate type, then pass that to the Expression.Lambda method. For example:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    
    class Test
    {
        static void Main()
        {
            var type = typeof(string);
            var body = Expression.Constant(true);
            var parameter = Expression.Parameter(type);
            var delegateType = typeof(Func<,>).MakeGenericType(type, typeof(bool));
            dynamic lambda = Expression.Lambda(delegateType, body, parameter);
            Console.WriteLine(lambda.GetType()); // Expression<string, bool>
        }
    }
    

    Now of course your body would normally not just be a constant - but we don't know what you need to do there. From your edited question, it looks like you do have some statically typed knowledge of the type, otherwise you wouldn't be able to express that lambda expression. So either you need to build up the expression tree manually to be the equivalent of the lambda expression (using Expression.Property etc) or create one expression tree from what you know, and then use an expression tree visitor to adapt that to the actual type.

    EDIT: Note that the type of lambda must be dynamic for it to work as the second argument to Queryable.Where, otherwise the execution-time version of the C# compiler will use the static type of the variable (which would just be LambdaExpression) to constrain overload resolution. You want it to match the actual Expression<TDelegate> type, which you can't express at compile-time, so you need to use dynamic.

    0 讨论(0)
提交回复
热议问题