,但我有一個項目其中:
int[] df = null; //GetDataFrame()
int xIndex = 12; //GetLearningIndex()
df[0] = 1 % GetLearningIndex();
,我意識到,當GetDataFrame回報空和GetLearningIndex返回零我得到一個System.DivideByZeroException
我期望根據像一個System.NullReferenceException
...任何原因?
,但我有一個項目其中:
int[] df = null; //GetDataFrame()
int xIndex = 12; //GetLearningIndex()
df[0] = 1 % GetLearningIndex();
,我意識到,當GetDataFrame回報空和GetLearningIndex返回零我得到一個System.DivideByZeroException
我期望根據像一個System.NullReferenceException
...任何原因?
這裏有一些混淆...... 部分首先評估賦值運算符的LHS。特別地,表達式df
和0
將在GetLearningIndex
之前被評估爲,但僅在之後發生的數組元素分配(包括索引驗證),結果已被計算。
這裏是展示一些細節的例子:
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;
的執行順序是:
arrayExpression
。沒有檢查結果是非空的,但評估表達式本身可能會拋出一個NullReferenceException
。indexExpression
。此時沒有對數組執行邊界檢查。valueExpression
這是目前嚴格規定,據我所知 - 我會提出一個問題,看看我們是否可以修復它在ECMA C#5標準。
當涉及數學運算時,首先評估左手操作數。在你的情況下,你正在調用一個返回一個值的方法:GetLearningIndex()
,在你使用它的任何數學運算之前,該值總是被評估。
這遠不是全部。重要的部分是在評估RHS之前評估'df [0]'的哪些部分。 –
你實際上是在引用那個文檔。如the actual one所述,分配運營商最終評估爲。因此,你的方法調用以及數學操作(%
是assignemtn在DivideByZeroException
屈服前評估。
此外,assignement運營商從右相反,留給所有被評估的其他二進制的評估從左至右:
除了賦值運算符,所有二進制運算符是 左結合,這意味着從左 右操作被執行。例如,X + Y + Z被評價爲(x。 + y)+ z 賦值運算符和條件運算符(?:)分別爲 ri ght-associative,這意味着操作從右到左執行到 。例如,x = y = z被評估爲x =(y = z)。
您鏈接的文檔是針對java的。 – Stuart
您鏈接的文檔顯示分配是從右到左的關聯。在你評估你的分配之前,你不能嘗試分配,你能嗎? –