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

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

请参阅此处: 为什么没有捕获的lambda从C#5中的静态更改为C#6中的实例方法?

在这里: CSC和Roslyn编译器的静态lambda表达式评估的差异?

现在,在创建静态MethodInfos以调用表达式方法(如Expression.Convert(Expression, typeof({SomeType}), conversionMethodInfo);会导致使用lambdas Expression.Convert(Expression, typeof({SomeType}), conversionMethodInfo);

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

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

是的,显然它不起作用。

那么,这样做的新方法是什么?

没有一个。 规范从未承诺任何关于lambda表达式的实现细节。 这就是为什么你不应该依赖它们。 这也是为什么C#6中的新function没有提到这一点。

假设您需要将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)Converter).Method; Expression.Convert(expression, typeof(SomeType), converter) 

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

如果其他人想知道,最后,我不得不将我的表达推广(降级)表达为“表达身体的function成员”,如下所示:

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

然后在我的方法体中:

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

编辑:有人在这里谈论非捕获/静态lambda: https : //github.com/dotnet/csharplang/issues/275