如何创建用于表达式构建的静态 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
从 C# 6 开始,lambda 现在默认为实例方法,并且永远不会是静态的(我认为这意味着它们现在总是捕获,我认为这更有效 [考虑到讨论似乎更快])。 =14=]
看这里:
这里:
这会导致在为调用表达式方法(例如 Expression.Convert(Expression, typeof({SomeType}), conversionMethodInfo);
那么,新的做法是什么?我尝试将 "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