質問

私はこの例を理解しようとしており、失敗し続けています。

これはコードです:

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

私は部分的に何が起こっているのかを知っていますが、そのラベルは私を混乱させているので、私の質問はラベルとは何かであり、そのローカル価値はブロックの最初のアイテムでどのように割り当てられ、使用されますか?

役に立ちましたか?

解決

ラベルはループを識別します。 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), 、「このラベルが言及するループから抜け出す」と書かれています。この場合、ブロックの単一ループです。

ローカル変数の場合、 Expression.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)
}                      // )
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top