59

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?

4
  • 3
    Console.WriteLine( String.Format( "{0}", (object)null )); This is fine too. Weird. Commented Dec 14, 2012 at 11:11
  • String.Format must be doing some work on the 2nd example, perhaps turning it into the null char? \0 </guesswork> Commented Dec 14, 2012 at 11:14
  • @DaveBish Hopefully Jon Skeet can answer why your example doesn't throw an exception. Commented Dec 14, 2012 at 11:25
  • The first case is passing in a null reference. The second case is passing in a (non-null) reference to a null string. Fine but significant distinction. Edit: I am not that familiar with C#, but I am assuming "String str = null;" is assigning a value to a declared object. If that's not the case, then I'm probably in error. Commented Dec 18, 2012 at 22:58

1 Answer 1

76

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.

Sign up to request clarification or add additional context in comments.

8 Comments

I bet you meant string.Format("{0}", values); on your last line of code. Anyway, there goes a +1 for typing what I was typing, just faster and more accurately ^^'
Where is the take my money button?
Also, maybe the answer should highlight why the compiler picks the most specific version of the function (it's easy to figure out for me, and I know it's even easier for you, but many readers may miss the detail that a null literal carries as little type information as a blank piece of paper).
Why doesn't string.Format("{0}", (object)null) throw an exception? And the docs only mention an exception if the format is null, not the args.
@juharr having one (or more, or all) member of the object array to be null is fine. Having the array itself being null ain't. It'd be nice for the string.Format(string, object[]) version to default null arrays into empty ones, but it just doesn't do that.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.