Math operations with null
C#C# Problem Overview
Please explain why this test passes?
[Test]
public void TestNullOps()
{
Assert.That(10 / null, Is.Null);
Assert.That(10 * null, Is.Null);
Assert.That(10 + null, Is.Null);
Assert.That(10 - null, Is.Null);
Assert.That(10 % null, Is.Null);
Assert.That(null / 10, Is.Null);
Assert.That(null * 10, Is.Null);
Assert.That(null + 10, Is.Null);
Assert.That(null - 10, Is.Null);
Assert.That(null % 10, Is.Null);
int zero = 0;
Assert.That(null / zero, Is.Null);
}
I don't understand how this code even compiles.
Looks like each math expression with null returns Nullable<T>
(e.g. 10 / null
is a Nullable<int>
). But I don't see operator methods in Nullable<T>
class. If these operators are taken from int
, why the last assertion doesn't fail?
C# Solutions
Solution 1 - C#
From MSDN:
The predefined unary and binary operators and any user-defined operators that exist for value types may also be used by nullable types. These operators produce a null value if the operands are null; otherwise, the operator uses the contained value to calculate the result.
That's why all the test are passed, including the last one - no matter what the operand value is, if another operand is null
, then the result is null
.
Solution 2 - C#
The operators for Nullable<T>
are so-called "lifted" operators]; the c# compiler takes the operators available for T
and applies a set of pre-defined rules; for example, with +
, the lifted +
is null
if either operand is null, else the sum of the inner values. Re the last; again, division is defined as null
if either operand is null
- it never performs the division.
Solution 3 - C#
I tried seeing the generated code from the code below using reflector
var myValue = 10 / null;
And the compiler turns it into this:
int? myValue = null;
And this wont compile, so you cant trick it:
object myNull = null;
var myValue = 10 / myNull;
Solution 4 - C#
I would assume that the compiler converts zero
to Nullable<int>
, and provides the underlying division operator. Since the Nullable
type may be null, the division by 0 is not caught during compile. Best guess is that they want you to be able to do null testing in cases where div/0 is occuring.
Solution 5 - C#
The operations in this list always return NULL:
1 + 2 + 3 + NULL
5 * NULL - 7
'Home ' || 'sweet ' || NULL
MyField = NULL
MyField <> NULL
NULL = NULL