【问题标题】:Implement Not in expression trees, .net 4在表达式树中实现 Not,.net 4
【发布时间】:2011-01-11 00:35:53
【问题描述】:

是否可以实现! (不)使用表达式树。我有兴趣创建一个 C# eval 类,它将解析和评估包含 true、false、||、&& 和 ! 的逻辑表达式。我知道 && 和 ||目前由 .NET 4 表达式树支持,但我想知道它们是否是一种实现 summat 的方法,例如 !(x && y) || z 其中 z=false,y=true 和 z=false。

目前我正在使用基于标准堆栈的标记器、解析器、评估器来评估这些类型的表达式,但如果可以动态创建和执行合适的表达式树,我很乐意将其转储。

【问题讨论】:

  • 标题说 .NET 4 但标签说 .NET 3.5。哪一个?
  • 3.5 当我上次检查时,它没有实现,但它现在在文档中,所以忽略 .net 条目。

标签: .net-3.5 c#-3.0 expression-trees


【解决方案1】:

我通常发现值得编写一个 lambda 表达式来执行我想要的操作,然后查看 C# 编译器如何处理它。

所以这段代码:

Expression<Func<bool,bool>> func = x => !x;

被编译成:

ParameterExpression expression2;
Expression<Func<bool, bool>> expression = 
       Expression.Lambda<Func<bool, bool>>(Expression.Not(
            expression2 = Expression.Parameter(typeof(bool), "x")), 
                new ParameterExpression[] { expression2 });

(为格式化道歉 - 很难知道如何处理。)

这是使用 Reflector 反编译的,但其“优化”设置为 .NET 2.0 以避免使用 lambda 语法。

一旦您通过了垃圾邮件,您就会看到它正在使用Expression.Not。 && 使用 Expression.AndAlso 和 ||使用Expression.OrElse

【讨论】:

  • 嗨乔恩,像往常一样,一个快速而出色的答案。鲍勃。
  • 很棒的技术,可以更好地了解引擎盖下发生的事情。
  • 我最初拥有完整的!(x &amp;&amp; y) || z,但它构建的代码太乱了:)
【解决方案2】:

这已经存在于System.Linq.Expressions 中。见UnaryExpression。除非有一些你不喜欢的表达方式,否则我建议使用它们。还有一些方法可以从源代码创建抽象语法树,特别是在 Microsoft.Scripting.Ast(在 DLR:Microsoft.Scripting 中找到)。

【讨论】:

    【解决方案3】:
    猜你喜欢
    • 2012-03-16
    • 1970-01-01
    • 2017-09-22
    • 2021-01-18
    • 1970-01-01
    • 2010-10-28
    • 2011-04-03
    • 2021-10-10
    • 1970-01-01
    相关资源
    最近更新 更多