C# 使用Lambda表达式(以及仅在运行时已知的类型)调用泛型方法

C# 使用Lambda表达式(以及仅在运行时已知的类型)调用泛型方法,c#,generics,lambda,expression,expression-trees,C#,Generics,Lambda,Expression,Expression Trees,可以使用将lambda表示为表达式 如果您在运行时只知道用于泛型方法签名的类型,那么如何创建表示泛型方法调用的类型 例如: 我想创建一个to call: publicstatictsource Last(此IEnumerable源代码) 但我只知道运行时的TSource是什么。静态表达式CreateLambda() static Expression<Func<IEnumerable<T>, T>> CreateLambda<T>() {

可以使用将lambda表示为表达式

如果您在运行时只知道用于泛型方法签名的类型,那么如何创建表示泛型方法调用的类型

例如:

我想创建一个to call:
publicstatictsource Last(此IEnumerable源代码)

但我只知道运行时的
TSource
是什么。

静态表达式CreateLambda()
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)
}
{ var source=Expression.Parameter( 类型(IEnumerable),“来源”); var call=Expression.call( typeof(可枚举),“Last”,新类型[]{typeof(T)},源); 返回表达式.Lambda(调用,源) }

静态LambdaExpression CreateLambda(类型)
{
var source=Expression.Parameter(
typeof(IEnumerable).MakeGenericType(type),“源”);
var call=Expression.call(
typeof(可枚举),“Last”,新类型[]{Type},源);
返回表达式.Lambda(调用,源)
}

我不完全理解这个问题,但dtb编写的代码可以简单地写成:

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

这种方法的好处是,
CreateLambda
中的代码可能要复杂得多,而明确使用表达式树确实很难做到这一点。

这还不完全清楚。您尝试在哪个对象上创建哪个方法?是否要使用lambda表达式引用最后一个泛型方法?@CasperOne:Hi Casper!a) 我试图创建一个对象的实例,它引用了该方法。b) 是的,我想用lambda表达式引用最后一个方法(我是说lambda表达式对象)。谢谢:)嗨,托马斯!我需要提高我的编程沟通技巧,我知道,我知道哈哈哈(但别担心,我正在努力:)。我更新了这个问题以表达我的真正意思。很好的重构+1@SDReyes:“在运行时”是重要的一点。不过,您仍然可以使用漂亮的C#语法(无需显式构造表达式树)。看看我的最新答案。嗨,托马斯!,我同意你的看法。这种方法可以让您在CreateLambda方法中轻松实现复杂的lambda(只需进行性能权衡)。这次我将使用dtb方法,因为我们正在开发的组件中已经使用了很多表达式,我想保持代码之间的一致性:)。但我也很乐意在接下来的场景中实现您的!干得好,托马斯!当做SD
class MyUtils {
  public static Expression<Func<IEnumerable<T>, T>> CreateLambda<T>() { 
    return source => source.Last();
  }
}
var createMeth = typeof(MyUtils).GetMethod("CreateLambda");
LambdaExpression l = createMeth.MakeGenericMethod(yourType).Invoke();