13

Straight to the point:

int? i = null;
i.ToString(); //happy
i.GetType(); //not happy

I get a very related question which actually deals on why does i.ToString() work fine.

Edit: Just found out this corner case has been the most voted one in this SO thread!

Community
  • 1
  • 1
nawfal
  • 70,104
  • 56
  • 326
  • 368

3 Answers3

7

It is because ToString is virtual while GetType is not. Nullables have special boxing behavior in the CLR. When you call GetType on a nullable it is boxed (see MSDN, actually this happens for any struct). However, with a nullable, the the underlying value is boxed, not the actual nullable. ToString on the other hand calls the override of ToString method on Nullable<T>. Also, I would note that int? i = null is syntax sugar for Nullable<int> i = new Nullable<int>(). So, there really is an object in your variable i.

Mike Zboray
  • 39,828
  • 3
  • 90
  • 122
  • At first I thought your last sentence is terribly wrong, but not!! That's unbelievable.. – nawfal Oct 14 '12 at 21:09
  • +1. The key is the boxing behavior. I actually sent almost the same question to Jon Skeet because it reminded me of his ".NET brain teasers" – CodingWithSpike Oct 15 '12 at 01:20
  • But I find this as one of the downsides of .NET. The less confusing, the better the language and framework is.. – nawfal Oct 15 '12 at 08:02
  • 1
    Another thing is that `GetType` works by examining the type descriptor of a heap object. The only way that can happen is if it has a heap object it can examine. Unfortunately, Microsoft decided that `Equals(null, default(int?))` should be true, so `default(int?)` boxes as `null` rather than as an `int?.Empty` value analogous to `String.Empty`. – supercat Oct 17 '12 at 17:13
3

Why does i.ToString() not fail?

Use any .NET decompiler and look at the Nullable<T> class. You'll see that ToString() is overriden as follows:

public override string ToString()
{
  if (!this.HasValue)
    return "";
  else
    return this.value.ToString();
}

Why does i.GetType() fail?

See mike z's answer.

Community
  • 1
  • 1
Cristian Lupascu
  • 39,078
  • 16
  • 100
  • 137
0

The type int? is not a regular type.

When you write int? i = null, only the value of the object being null, but not the object itself.

The object int? inheritance from object, so the function i.ToString() can work, and it work on the value that inside the object.

user1745470
  • 85
  • 1
  • 6