2017-04-24 5 views
-4

は、右の前に評価されます...左オペランドが最初に壊れていますか?この<a href="https://msdn.microsoft.com/en-us/library/2bxt6kc4.aspx" rel="nofollow noreferrer">here</a></p> <p>左側に応じ

が、私はプロジェクトがあります:私は実現

int[] df = null; //GetDataFrame() 
int xIndex = 12; //GetLearningIndex() 
df[0] = 1 % GetLearningIndex(); 

をして、ときGetDataFrame戻りヌルGetLearningIndexは0を返す私はSystem.DivideByZeroExceptionを得る私は好きなように期待するだろうSystem.NullReferenceException ...なんで?

+0

リンク先のドキュメントは、java用です。 – Stuart

+1

あなたがリンクしているドキュメントは、その割り当てが右から左への結合であることを示しています。割り当てを評価する前に割り当てを試すことはできません。 –

答えて

2

ここでは混乱があります。代入演算子のLHSのが最初に評価されます。特に、式df0GetLearningIndexが評価されるが、(インデックスの検証を含む)配列要素の割り当ては、結果が計算された後に起こります。

はここにいくつかの詳細を示した例です。この形の文でそう

using System; 

public class Test 
{ 
    private int[] array = new int[10]; 

    static void Main() 
    { 
     Test instance = null; 

     // This would throw a NullReferenceException 
     // because instance is null at the start of the statement. 
     // ExecuteSideEffect never gets called.   
     // instance.array[100] = ExecuteSideEffect(() => instance = new Test()); 

     instance = new Test(); 

     // This would throw an IndexOutOfBoundsException 
     // because instance.array is evaluated before ExecuteSideEffect. 
     // The exception is only thrown when the assignment is performed. 
     // instance.array[100] = ExecuteSideEffect(() => instance.array = new int[1000]); 

     int index = 5; 
     // This modifies array index 5 because index is evaluated 
     // before EvaluateSideEffect 
     instance.array[index] = ExecuteSideEffect(() => index = 1); 
     Console.WriteLine(instance.array[5]); // 10 
    } 

    private static int ExecuteSideEffect(Action action) 
    { 
     action(); 
     return 10; 
    } 
} 

arrayExpression[indexExpression] = valueExpression; 

実行順序は次のとおりです。

  1. arrayExpressionを評価します。結果がnullではないというチェックはありませんが、式の評価自体がNullReferenceExceptionです。
  2. indexExpressionを評価してください。この時点で、アレイに対して境界チェックは実行されません。
  3. valueExpressionを評価する配列要素を配列参照がnullであり、配列インデックスが有効であることのチェックがされている3 これがあるステップの結果にステップ1及び2の結果を用いて表現設定実行されます。

これは現在のところ私が言うことができる限り厳密に指定されています。問題をECMA C#5標準で修正できるかどうかを確認します。

4

数値演算では、左側のオペランドが最初に評価されます。あなたのケースでは、値を返すメソッドを呼び出しています:GetLearningIndex()この値は、それを使用する数学演算の前に常に評価されます。

+0

これは全体の話から遠いです。重要な部分は、RHSが評価される前に 'df [0]'のどの部分が評価されるかです。 –

0

本当に間違ったドキュメントを参照しています。 the actual oneで言及されているように、割り当てオペレータは最後にと評価されます。したがって、あなたのメソッド呼び出しと数学演算(%は、DivideByZeroExceptionで代入する前に評価されます。

さらに、代入演算子は評価される他のバイナリ演算子とは異なり、右から左に評価されます左から右へ:代入演算子を除い

、すべてのバイナリ演算子は、右 左から操作が実行されることを意味し、 左連想される。例えば、X + Y + Zは、(Xとして評価されます。 + y)+ z。 代入演算子と条件演算子(?:)は riです。 ght-associativeは、右から まで操作が実行されることを意味します。例えば、x = y = zは、x =(y = z)として評価される。

関連する問題

 関連する問題