Using Lambda Expressions to Call a Generic Method (and a Type only known at runtime)

c# expression expression-trees generics lambda

Question

A lambda may be represented as an expression with the notation Objects for Lambda Expression.

If you only know the type you choose for the generic method signature at runtime, how do you build a Object for Lambda Expression indicating a generic method call?

For instance:

To call, I wish to make a Objects for Lambda Expression.public static TSource Last<TSource>( this IEnumerable<TSource> source )

But all I know is whatTSource During runtime.

1
16
5/17/2010 3:56:54 PM

Accepted Answer

static Expression<Func<IEnumerable<T>, T>> CreateLambda<T>()
{
    var source = Expression.Parameter(
        typeof(IEnumerable<T>), "source");

    var call = Expression.Call(
        typeof(Enumerable), "Last", new Type[] { typeof(T) }, source);

    return Expression.Lambda<Func<IEnumerable<T>, T>>(call, source)
}

or

static LambdaExpression CreateLambda(Type type)
{
    var source = Expression.Parameter(
        typeof(IEnumerable<>).MakeGenericType(type), "source");

    var call = Expression.Call(
        typeof(Enumerable), "Last", new Type[] { type }, source);

    return Expression.Lambda(call, source)
}
27
5/17/2010 3:57:06 PM

Popular Answer

I'm not sure I understand the query, however the dtb code may be expressed as follows:

class MyUtils {
  public static Expression<Func<IEnumerable<T>, T>> CreateLambda<T>() { 
    return source => source.Last();
  }
}

The code generated by the C# compiler from this lambda expression (compiled as an expression tree since the return type is a lambda) is almost identical to that in the dtb example.Expression ).

If you are aware of the type at runtime, you may either use the dtb solution or use theCreateLambda Although it could take longer, the way (above) utilizing Reflection enables you to construct lambda-style code:

var createMeth = typeof(MyUtils).GetMethod("CreateLambda");
LambdaExpression l = createMeth.MakeGenericMethod(yourType).Invoke();

The benefit of this strategy is that the code inCreateLambda It would be quite difficult to use expression trees directly for something that may be considerably more intricate.



Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow