c# - 卡在表达式树中

标签 c# expression-trees

我试图理解这个例子,但总是失败。

这是代码:

// Creating a parameter expression.
ParameterExpression value = Expression.Parameter(typeof(int), "value");

// Creating an expression to hold a local variable. 
ParameterExpression result = Expression.Parameter(typeof(int), "result");

// Creating a label to jump to from a loop.
LabelTarget label = Expression.Label(typeof(int));

// Creating a method body.
BlockExpression block = Expression.Block(
    // Adding a local variable. 
    new[] { result },
    // Assigning a constant to a local variable: result = 1
    Expression.Assign(result, Expression.Constant(1)),
    // Adding a loop.
        Expression.Loop(
    // Adding a conditional block into the loop.
           Expression.IfThenElse(
    // Condition: value > 1
               Expression.GreaterThan(value, Expression.Constant(1)),
    // If true: result *= value --
               Expression.MultiplyAssign(result,
                   Expression.PostDecrementAssign(value)),
    // If false, exit the loop and go to the label.
               Expression.Break(label, result)
           ),
    // Label to jump to.
       label
    )
);

我知道部分发生了什么,但那个标签让我感到困惑,所以我的问题是什么是标签,以及如何在 block 的第一项中开始分配和使用该局部值?

最佳答案

一个标签标识一个循环。我能理解你的困惑,因为 C# 实际上没有循环标签,但 .NET 确实在内部使用它们,因此它们被用在 .NET 的表达式树中。下面是一些示例 Java 代码(确实有循环标签):

outerLoop: // This is a label for the outer loop
while (true) {
    innerLoop: // This is a label for the inner loop
    while (true) {
        // Rather than exiting the inner loop (which is what a plain break would
        // do), this exits the outer loop
        break outerLoop;
    }
}

Expression.Loop 方法将一个标签作为参数,表示“这个标签指向这个循环”。当您有 Expression.Break(label, result) 时,它表示“跳出此标签引用的循环”,在本例中是 block 的单个循环。

对于局部变量,Expression.Block 的第一个参数声明了作用域为该 block 的所有局部变量。所以 result 首先声明,然后由 Expression.Assign 调用初始化。

生成的表达式树大致等同于此 C# 代码:

{                      // Expression.Block(
    int result;        //   new[] { result },
    result = 1;        //   Expression.Assign(result, Expression.Constant(1)),
    while (true)       //   Expression.Loop(
    {                  
        if (value > 1) //     Expression.IfThenElse(
        {              //       Expression.GreaterThan(value, Expression.Constant(1)),
            result *=  //       Expression.MultiplyAssign(result,
              value--; //       Expression.PostDecrementAssign(value)),
        }
        else             
        {
            break;     //       Expression.Break(label, result)
        }              //     ),
    }                  //   label)
}                      // )

关于c# - 卡在表达式树中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19845888/

相关文章:

c# - 试图理解什么是表达式树

c# - 如何根据枚举的类型和字段之一的名称创建枚举的表达式?

c# - 表达式树和调用委托(delegate)

c# - 协商了哪个 TLS 版本?

c# - 事务和锁

c# - Inspector 中的 Unity3d 二维数组

c# - 为什么我应该使用 IDisposable 而不是在 c# 中使用?

c# - 把逗号放在小数中

c# - 通过表达式调用可枚举平均值

c# - 表达式树的部分应用