Why do I get an exception when passing "null" constant but not when passing a "null" string reference?

C#.NetReferenceArgumentnullexception

C# Problem Overview


If I run this code:

Console.WriteLine( String.Format( "{0}", null ) );

I get a ArgumentNullException but if I run this code:

String str = null;
Console.WriteLine( String.Format( "{0}", str ) );

it runs just fine and the output is an empty string.

Now the two piece look equivalent to me - they both pass a null reference into String.Format() yet the behavior is different.

How id different behavior possible here?

C# Solutions


Solution 1 - C#

Just decompile the code to work out what's going on.

string.Format("{0}", null)

calls the most specific applicable overload, which is string.Format(string, object[]).

The overloads of string.Format are:

Format(String, Object)
Format(String, Object[])
Format(IFormatProvider, String, Object[])
Format(String, Object, Object)
Format(String, Object, Object, Object)

Hopefully it's obvious why the last three options are invalid.

To work out which of the first two to use, the compiler compares the conversion from null to Object to the conversion from null to Object[]. The conversion to Object[] is deemed "better" because there's a conversion from Object[] to Object, but not vice versa. This is the same logic by which if we had:

Foo(String)
Foo(Object)

and called Foo(null), it would pick Foo(String).

So your original code is equivalent to:

object[] values = null;
string.Format("{0}", values);

At this point, hopefully you'd expect an ArgumentNullException - as per the documentation.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsharptoothView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow