Chapter 4: Saying nothing with nullable types: 4.3.3
Last updated: 3/21/2008
Ross Bradbury posted an interesting question on the C# in Depth Forum. It was sufficiently unexpected that we reckoned it was worth a note.
He had code which effectively looked like this (I've pared it down a little):
public static implicit operator Test(int i)
Console.WriteLine("Converted from "+i);
return new Test();
static void Main()
int a = 10;
Test normalConversion = a;
int? b = 20;
Test unexpectedConversion = b;
int? c = null;
Test evenOdder = c;
The first conversion (
normalConversion = a) is entirely normal -
Test, using the implicit conversion. This prints 10.
The second conversion (
unexpectedConversion = b) is one which I didn't expect to be legal - after all, we have an
int? rather than an
int, and there's no implicit conversion from
int. However, it compiles and runs, and prints 20.
What would it print if we were to convert from a null value? Well, that's what the third conversion (
evenOdder = c) checks. Again, it compiles and executes without an exception - but nothing gets printed. The result is a null reference.
It turns out that the C# compiler is handling this as a lifted conversion - so it checks whether or not the source has a value or not, and returns a null value if not. If there is a value, it performs the appropriate conversion.
This is a compiler bug (confirmed by Eric). It's not behaving as per the spec (which disallows it) but the behaviour is unlikely to change now as it would break existing code.