【问题标题】:How to create a static lambda for use with expression building?如何创建用于表达式构建的静态 lambda?
【发布时间】:2017-08-30 06:44:18
【问题描述】:

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

请看这里:Why has a lambda with no capture changed from a static in C# 5 to an instance method in C# 6?

这里:Difference in CSC and Roslyn compiler's static lambda expression evaluation?

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

那么,这样做的新方法是什么?我尝试将“静态”修饰符与 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)

是的,显然它不起作用。

【问题讨论】:

  • 您能告诉我们您“尝试过”什么以及为什么您认为“它不起作用”吗?
  • 当规范发生变化而现在没有关于新事物的文档时,谁能尝试任何东西?大声笑想象一个 lambda 表达式,然后想象所有在其上放置“静态”修饰符的方法,这就是我尝试过的(我知道这是不可能的,但以防万一他们足够聪明,可以将其放入此版本中以进行补偿) .
  • 您是否有理由不能将其提升为私有静态表达式值成员?
  • 是的,因为它不能解决问题。 ;)(也不回答问题)
  • 那为什么要停在那里?只需将其提升为实际的静态方法,然后在我的课堂上乱扔它们。 ;) 我希望将它们分组在它所使用的唯一方法中,但现在我可能不得不“弄脏”我的班级。

标签: c# lambda c#-6.0


【解决方案1】:

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

没有。该规范从未承诺任何关于 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 方法。

【讨论】:

  • @downvoter 你想评论一下你认为这个答案有什么问题吗?
  • 有人也对我的投了反对票,哈哈。也许他们有更好的想法,但希望自己保留。 ;)
【解决方案2】:

如果其他人想知道,最后,我不得不将我的表达式提升(降级?lol)为“表达式体函数成员”,如下所示:

// (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);

编辑:这里有一些关于非捕获/静态 lambda 的讨论:https://github.com/dotnet/csharplang/issues/275

【讨论】:

  • 我不认为强迫人们最终用私有静态表达式来混乱他们的类是一个明智的决定,但我们只能希望有一天“静态”修饰符也可以在 lambdas 上工作。虽然一件事可能更有效,但另一件事变得更烦人。这就像向前迈出一步,又向后迈出一步,但是哦。
  • 大声笑,对适合我的解决方案投反对票,无需解释,好的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多