如何创建用于表达式构建的静态 lambda?

How to create a static lambda for use with expression building?

从 C# 6 开始,lambda 现在默认为实例方法,并且永远不会是静态的(我认为这意味着它们现在总是捕获,我认为这更有效 [考虑到讨论似乎更快])。 =14=]

看这里:

这里:

这会导致在为调用表达式方法(例如 Expression.Convert(Expression, typeof({SomeType}), conversionMethodInfo);

创建静态 MethodInfos 时使用 lambda 出现问题

那么,新的做法是什么?我尝试将 "static" 修饰符与 lambda 一起使用,但它不起作用。对于那些无法想象这样的代码的人,这可能是一个例子:

Func <T1,T2> converter = static v => ConvertT1ToT2(v); // ('T' is whatever type you want)
Expression.Convert(expression, typeof({SomeType}), converter.Method) // (error: converter.Method.IsStatic is false)

是的,显然不行。

So then, what is the new way of doing this?

没有一个。该规范从未对 lambda 表达式的实现细节做出任何承诺。这就是为什么你不应该依赖他们。这也是What's new in C# 6没有提到这个的原因。

假设您需要将 Expression.Convert 与自定义 MethodInfo 一起使用,那么您应该将 lambda 提升为 static 方法:

private static T2 Converter(T1 v)
{
    return ConvertT1ToT2(v);
}

…

MethodInfo converter =
    typeof(ThisType).GetMethod("Converter", BindingFlags.NonPublic | BindingFlags.Static);
// OR:
MethodInfo converter = ((Func<T1, T2>)Converter).Method;

Expression.Convert(expression, typeof(SomeType), converter)

这样,您就不会使用 lambda,因此可以保证 MethodInfo 指的是 static 方法。

以防别人想知道,最后,我不得不把我的表情提升(降级?哈哈)改为"Expression-bodied function members",像这样:

// (class method)
static string _Convert(object obj) => (obj as SomeType)?.SomeProperty ?? ReturnSomethingElse;

然后在我的方法体中:

Func<object, string> conversionDelegate = _Convert;
Expression exp = Expression.Convert(expression, typeof(SomeType), conversionDelegate.Method);

编辑:这里有些关于 non-capturing/static lambda 的讨论:https://github.com/dotnet/csharplang/issues/275