Convert.ToInt32(String) on String.Empty vs. Null

58,101

I have absolutely no insight into the actual design team's reasoning behind this, but it seems to me that it might be some sort of "default value equivalency". Null is the default value of string, so it seems logical to convert it to a default value of int. String.Empty is however a string like any other non-null string data, so it is expected to be formatted, hence the exception.

I think ArgumentNullException would have been a "cleaner" decision, but I don't know whatever internal issues may be behind this all...

Another edit:
There, right in the MSDN documentation, one of the 5 possible outcomes:

A successful conversion. For conversions between two different base types not listed in the previous outcomes, all widening conversions as well as all narrowing conversions that do not result in a loss of data will succeed and the method will return a value of the targeted base type.

It seems the conversion from null object to another type has no reason to fail (not a format error, not an unsupported type conversion), but a value type such as int has no representation of "no data", so a default value of the target type is produced.

A quick thought - the "opposite" conversion, Convert.ToString(0), does not yield null because:

  • 0 is data, it can be very valid and important value in many cases
  • null is not a correct string representation of 0
Share:
58,101

Related videos on Youtube

MCattle
Author by

MCattle

Software developer who's been working with .Net since 1.0, and several obscure languages before that (remember Miranda, or Mex?)

Updated on July 09, 2022

Comments

  • MCattle
    MCattle almost 2 years

    The expression Convert.ToInt32(String.Empty) will raise a FormatException because it cannot parse an empty string into an Int32 value.

    However, the expression Convert.ToInt32(DirectCast(Nothing, String)) in VB.NET or Convert.ToInt32((string)null) in C# will parse the null to an Int32 value of zero.

    Digging into the .NET source in Convert.cs, I see the following code:

    public static int ToInt32(String value) {
        if (value == null) 
            return 0;
        return Int32.Parse(value, CultureInfo.CurrentCulture);
    }
    

    This explains the behaviour, but I'd like to understand why it was written this way, instead of returning a zero for an empty string as well?

    For example, why wasn't it written as:

    public static int ToInt32(String value) {
        if (String.IsNullOrEmpty(value)) 
            return 0;
        return Int32.Parse(value, CultureInfo.CurrentCulture);
    }
    

    (Note that String.IsNullOrEmpty() and Convert.ToInt32() both date back to .NET 2.0, possibly earlier.)

    Edit: My question is very similar to this question, but I'd also like to know why Convert.ToInt32(String.Empty) raises an exception instead of returning the Int32 default value of 0. (The answer being that String.Empty is not the default value of String, so there's no correlation.)

    • Jon Skeet
      Jon Skeet about 11 years
      Null can be viewed as an absence of data - whereas an empty string is a string, just an empty one... and that's not a number. (Personally I'd prefer it not to be so lenient with null, but that's a different matter.)
    • Matthew Watson
      Matthew Watson about 11 years
      +1 for interesting question. I'd have expected it to throw an exception, just like passing "" will. Especially when Int32.Parse(null) throws an exception! (Ok, ok, it's the subtle difference between converting and parsing - but even so...)
    • yairr
      yairr about 11 years
      If you really want to blow your mind with this type of question compare and contract SQL NULL vs C# null.
    • Andre Loker
      Andre Loker about 11 years
      Interesting question. TBH I think it's a bad design choice. Neither null nor "" are valid integers in my opinion and both should cause an exception.
    • Steven
      Steven about 11 years
      I would expect this API to throw a NullReferenceException, not returning the default value. Looking at the rest of the .NET framework API, that would be theost reasonable thing to do.
    • JDB
      JDB about 11 years
      As the votes currently stand, the second answer to the "duplicate" question answers this question (the "why" part): stackoverflow.com/a/11580256/211627
    • Anthony Pegram
      Anthony Pegram about 11 years
      I worked* on a legacy app, and you would be surprised at how many places it was literally hardcoded as long someValue = Convert.ToInt64(null); Maddening. That was my first introduction to this behavior, because at first sight, I was convinced it was a ticking time bomb.
    • SASS_Shooter
      SASS_Shooter about 11 years
      I'm only guessing on this, haven't learned to read Anders' mind yet, but all value types have a default of natural 0. So they may say null defaults to natural zero, while an empty string (as said by Skeet) is just a string.
    • Matthew Watson
      Matthew Watson about 11 years
      >but all value types have a default of natural 0.< Well you might think that, but then why does Convert.ToChar(null) throw an exception? ;) (Answer: Because Char isn't a numeric type.)
  • MCattle
    MCattle about 11 years
    I'll accept this as it scratches my curiosity itch. The "VB6 Legacy Support" answer in stackoverflow.com/questions/11580208/… that @Cyborgx37 posted in a comment to the original question also appears to be a valid reason to me.
  • Honza Brestan
    Honza Brestan about 11 years
    Very interesting. Also relevant to today's XKCD strip :) xkcd.com/1172
  • Jonathan
    Jonathan over 9 years
    I don't think that rationale holds since according to the MSDN link a FormatException should be thrown since "A string to be converted to any numeric type is not recognized as a valid number.".
  • nawfal
    nawfal almost 9 years
    @HonzaBrestan not sure how you would then explain int.Parse(null) giving exceptions. Weird choice but my reasoning will be like "because documentation says so".