使用 Lambda 表达式调用通用方法(以及仅在运行时知道的类型)
Posted
技术标签:
【中文标题】使用 Lambda 表达式调用通用方法(以及仅在运行时知道的类型)【英文标题】:Calling a Generic Method using Lambda Expressions (and a Type only known at runtime) 【发布时间】:2011-02-20 11:19:19 【问题描述】:您可以使用Lambda Expression Objects 将 lambda 表示为表达式。
如果您只知道在运行时用于泛型方法签名的类型,如何创建代表泛型方法调用的Lambda Expression Object?
例如:
我想创建一个Lambda Expression Objects 来调用:
public static TSource Last<TSource>( this IEnumerable<TSource> source )
但我只知道 TSource
在运行时是什么。
【问题讨论】:
这并不完全清楚。您要在哪个对象上创建哪种方法?你想用 lambda 表达式引用 Last 泛型方法吗? @CasperOne:嗨,Casper! a) 我正在尝试创建一个引用 TheMethod 的 TheObject 实例。 b) 是的,我想用 lambda 表达式(我的意思是 lambda 表达式对象)引用最后一个方法。谢谢:) 【参考方案1】: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)
或
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)
【讨论】:
【参考方案2】:我没有完全理解这个问题,但是dtb写的代码可以简单地写成:
class MyUtils
public static Expression<Func<IEnumerable<T>, T>> CreateLambda<T>()
return source => source.Last();
dtb 示例中的代码与 C# 编译器从该 lambda 表达式自动为您生成的代码几乎相同(编译为表达式树,因为返回类型为 Expression
)。
如果您在运行时知道类型,那么您可以使用 dtb 解决方案,也可以使用反射调用 CreateLambda
方法(上图),这可能会更慢,但允许您在 lambda 中编写代码在自然的 C# 中:
var createMeth = typeof(MyUtils).GetMethod("CreateLambda");
LambdaExpression l = createMeth.MakeGenericMethod(yourType).Invoke();
这种方法的好处是CreateLambda
中的代码可能要复杂得多,这很难显式使用表达式树。
【讨论】:
嗨,托马斯!我需要提高我知道的编程沟通技巧,我知道哈哈哈(但别担心我正在努力:)。我更新了问题以代表我的真正意思。不错的重构! +1 @SDReyes:“在运行时”是重点。不过,您仍然可以为此使用漂亮的 C# 语法(无需显式构造表达式树)。请参阅我的更新答案。 嗨,托马斯!,我同意你的看法。这种方法让您可以在 CreateLambda 方法中轻松实现复杂的 lambda(只需权衡性能)。这次我将使用 dtb 方法,因为我们已经在我们正在处理的组件中使用了很多表达式,并且我想保持代码之间的连贯性:)。但我也很乐意在接下来的场景中实现你的!干得好托马斯!问候。标清以上是关于使用 Lambda 表达式调用通用方法(以及仅在运行时知道的类型)的主要内容,如果未能解决你的问题,请参考以下文章
std::function()函数std::bind()函数以及lambda