-4

This obviously results in an error:

null.ToString();

Why does this ToString not get the same error:

int? foo = null;
foo.ToString(); // 0, why no error?
0 == foo; // false
null == foo; // true
null == 0; // false

I get that there is some internal magic going on, but it seems bizarre to me that foo.ToString() would return 0 when the value isn't equal to int 0.

Developer Webs
  • 983
  • 9
  • 29
  • 2
    The code you posted doesn't do what you claim it does. `foo.ToString()` will return `"0"` only if the nullable `int` is in fact non-null. When it has the `null` value, `ToString()` returns the empty string `""`, exactly as the documentation promises it will. – Peter Duniho Jul 13 '19 at 05:49
  • 3
    Note that `null.ToString();` wouldn't even compile: "error CS0023: Operator '.' cannot be applied to operand of type ''". Please provide a [mcve] which demonstrates behaviour you don't understand - as Peter says, calling `ToString()` on a null value of any `Nullable` will return an empty string. – Jon Skeet Jul 13 '19 at 06:06
  • @PeterDuniho I no longer have the original. Instead of assigning null to foo I was calling a class function that was returning null, I think the return type of the function was int?. A ToString call on the return type was an empty string I believe. – Developer Webs Jul 14 '19 at 13:32

1 Answers1

2

Here is a line-to-line analysis of your code.

null.ToString();

Here a method is called on a null reference. Of course exception would be thrown.

int? foo = null;

This creates a struct foo of type Nullable<int> on the stack, and has its HasValue property to false.

foo.ToString();

This calls the ToString() method of Nullable<T>, which is overridden to return an empty string ("").(In your question you said that returns 0. This is not true.) Note that calling an overridden method directly on a value type does not cause boxing.

0 == foo

This works and returns false because 0 is converted into a Int32? which contains a value, but foo does not contain any value. See this answer about nullable type conversion about and documentation about lifted operators

null == foo;

Works and returns true because null is converted to Int32? which does not contain any value. This equals foo, which also doesn't contain any value.

null == 0

Works and returns false because null is converted to Int32? and 0 is converted to Int32? but the former contains no value.

ph3rin
  • 4,426
  • 1
  • 18
  • 42