according to this here
left will be evaluated before right...
but I have a project where:
int[] df = null; //GetDataFrame()
int xIndex = 12; //GetLearningIndex()
df[0] = 1 % GetLearningIndex();
and I realized, when GetDataFrame returns null and GetLearningIndex returns zero I get an System.DivideByZeroException
I would expect according to the like a System.NullReferenceException
...any reason why??
There's some confusion here... parts of the LHS of the assignment operator are evaluated first. In particular, the expressions df
and 0
will be evaluated before GetLearningIndex
, but the array element assignment (including index validation) only occurs after the result has been calculated.
Here's an example showing some more details:
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;
}
}
So in a statement of this form:
arrayExpression[indexExpression] = valueExpression;
the execution order is:
arrayExpression
. There's no check that the result is non-null, but evaluating the expression may itself throw a NullReferenceException
.indexExpression
. No bounds check is performed on the array at this point.valueExpression
This is currently badly specified as far as I can tell - I'll raise an issue to see if we can fix it in the ECMA C# 5 standard.
See more on this question at Stackoverflow