根据此here
左边将在右边评估......
但我有一个项目:
int[] df = null; //GetDataFrame()
int xIndex = 12; //GetLearningIndex()
df[0] = 1 % GetLearningIndex();
我意识到,当 GetDataFrame 返回 null 且 GetLearningIndex 返回零时,我会得到一个System.DivideByZeroException
我希望根据像System.NullReferenceException
...任何理由??
答案 0 :(得分:4)
在数学运算方面,首先评估左手操作数。在您的情况下,您正在调用一个返回值GetLearningIndex()
的方法,该值将始终在您使用它的任何数学运算之前进行求值。
答案 1 :(得分:2)
这里有一些混淆......首先评估赋值运算符的LHS的 parts 。特别是,表达式df
和0
将在 GetLearningIndex
之前计算,但数组元素赋值(包括索引验证)仅在之后 / em>结果已计算完毕。
以下是一个显示更多细节的示例:
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标准中修复它。
答案 2 :(得分:0)
你实际上是在引用错误的文件。正如在the actual one中所提到的那样,最终评估了分配运算符 。因此,在%
中的assignemtn屈服之前,会对您的方法调用以及数学运算(DivideByZeroException
进行评估。
此外,从左到右评估了从右到左的分配操作符,与从左到右评估的所有其他二进制操作符进行了对比:
除赋值运算符外,所有二元运算符都是 左关联,意味着操作从左到右执行 对。例如,x + y + z被评估为(x + y)+ z。该 赋值运算符和条件运算符(?:)是 右关联,意味着操作从右到右执行 剩下。例如,x = y = z被评估为x =(y = z)。