Convert vs. Parse

4. February 2012

Convert vs. Parse

There are at least two ways to convert a standard string type to an value type:

Convert.ToInt32

and

Int32.Parse

These two ways seem to be identical, but there aren’t. I used Lutz Reflector to show the differences:

Int32.Parse calls

public static int Parse(string s, NumberStyles style, IFormatProvider provider)
{
  NumberFormatInfo info1 = NumberFormatInfo.GetInstance(provider);
       NumberFormatInfo.ValidateParseStyle(style);
       return Number.ParseInt32(s, style, info1);
}

and Number.ParseInt32 is defined as InternalCall:

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern int ParseInt32(
string
s, NumberStyles style, NumberFormatInfo info);

Here is the code for Convert.ToInt32(string)

public static int ToInt32(string value)
{
if (value == null)
{
return 0;
}

return int.Parse(value); }

Here you see the difference: Convert checks, if the argument is null and returns 0 in this case, instead of directly throwing an exception. If you don’t need this behavior, calling Int32.Parse is a (little bit) faster than calling Convert.ToInt32. Same is true for the hundred other Xxx.Parse and Convert.Xxx calls.

In addition: we should better use int.Parse instead of int32.parse. Do you want to now the reason? Read Clemens Vasters article.

Keine verwandten Artikel gefunden.

Comments

  1. Avinash says:

    Hi,
    Interesting post. I was hoping you could throw some light on the following:

    Given that data in a data set may be accessed via the tables row collection and also each data value is returned as an ‘object’ we will need to cast it to the correct types as necessary.
    for example
    dataRow["colname"].ToString() will be ok for string cols,
    and (datetime) dataRow["colname"] will be ok for dates,

    but (int) dataRow["colname"] will not work.
    convert.ToInt32(dataRow["colname"]) will be ok, but from your post
    ToInt32 will internally call int.Parse(value);

    If I understand it correctly, parse will use the currnt threads culture info to parse the value.

    What I am Totally Totally not sure about is :
    Suppose your DB server is running on a machine that is configured to use a culture other than the one your app server is running on, will it cause incorrect format exception ?
    Will using parametrized sql and ADO Commands with named parameters be adequate. ie will separation of the command stream and data steam be adequate to make it all work seamlessly ?
    Are there any best practices around this ?

    Regards,
    Avinash

  2. Avinash, yes, parse will use the current threads culture info, because it internally calls Parse with IFormatProvider = null. As you can see in the IL dissassembly, there is a fundametal difference between calling

    (int) dataRow[�colname�]
    unbox.any [mscorlib]System.Int32
    stloc.0
    convert.ToInt32(dataRow[�colname�])
    call int32 [mscorlib]System.Convert::ToInt32(object)
    stloc.0

    Using (int) only unboxes the object to the requested type, but convert.ToInt32 calls the ToInt32 fucntion.

    The values are always converted on the local machine, so it depends uppon the local machine, if it will call an incorrect format exception. Using parametrized sql and storing the most generic data format in the sql server seems to me the best solution. Only convert to localized values on the client, not on the server.

    Markus

Speak Your Mind

*