【问题标题】:What does System.Linq.Expressions.Expression.CanReduce property mean?System.Linq.Expressions.Expression.CanReduce 属性是什么意思?
【发布时间】:2015-04-24 12:22:40
【问题描述】:

the documentation 及其名称暗示可以推断,对于可以进一步分解为更小的表达式的所有表达式,CanReduce 属性的值必须设置为 true,反之亦然。

但仔细观察后,这种推论似乎并非在所有情况下都成立。以LambdaExpression 为例,它肯定是一个复合单元。但是直接从Expression 类派生的LambdaExpression 类不会覆盖CanReduce 属性。 Expression 类将 CanReduce 属性定义为虚拟,并实现返回 false,因此暗示 lambda 表达式不能进一步简化,这是不正确的。

那么这个属性的真正含义是什么?

【问题讨论】:

  • 例如复合赋值a+=b可以简化为a=a+b
  • 不错。谢谢你。意思是否仅限于这些运算符(我忘记它们叫什么了)?
  • 我对@9​​87654334@没有深入研究,要说它是真是假。
  • 非常感谢您。我想我发现了一些在这种情况下可能有用的东西,在这里:stackoverflow.com/a/2044367/303685
  • .NET 4.0: What does Expression.Reduce() do? 的可能重复项(我知道,您问的是CanReduce,而不是Reduce。但是,如果您了解后者的作用,您将更接近理解前者。)

标签: linq linq-expressions custom-linq-providers


【解决方案1】:

我在这里发布了一个更长的答案,其中包含更多细节:What does Expression.Reduce() do?,但简短的形式是开箱即用的 .NET 行为似乎只会减少以下情况:

  • 复合赋值,例如x += 4
  • 前/后递增/递减,例如x++, --y
  • 成员和列表初始化,例如new List<int>() { 4, 5 }, new Thing() { Prop1 = 4, Prop2 = 5 }

其他一切都保持原样。我没有看到任何证据支持或反对将死表达式剔除作为 reduce 操作的一部分(例如,在 Reduce() 调用期间不会从表达式树中删除空的 BlockExpression)。

【讨论】:

  • 漂亮、实用、好用,随你答。谢谢。
【解决方案2】:

我认为您阅读文档的方式有误。这里的“化简”并不是说分解成多个更简单的表达式,而是转化成一个使用更多基本操作的表达式。例如,考虑以下ListInitExpression(使用类似 C# 的语法):

new List<int> { 1, new Random().Next() }

在此表达式上调用 CanReduce 将返回 true。调用Reduce() 将返回:

{
    Param_0 = new List<int>();
    Param_0.Add(1);
    Param_0.Add(new Random().Next());
    return Param_0;
}

我不清楚 Reduce() 应该在 LambdaExpression 返回什么,所以对我来说它是不可还原的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-13
    • 2016-04-06
    • 2016-06-07
    • 1970-01-01
    • 2019-06-12
    • 2010-10-23
    • 2018-12-10
    • 1970-01-01
    相关资源
    最近更新 更多