The Difference Between int.Parse() and System.Convert.ToInt32()

When you want to convert a string to an integer the two most popular approaches are to use int.Parse() or System.Convert.ToInt32(), both of which are static functions. (I’m not going to include int.TryParse(), System.Convert.ChangeType(), etc. in this discussion). Personally I always use int.Parse(), why? Well I don’t actually have a good reason; I’ve always just thought it looks cleaner.

So why would you choose to use one over the other? Well I guess it really depends on what you need; from my short investigation I was able to spot the following differences:

  • Passing a null string into int.Parse() will throw an ArgumentNullException. Passing a null string into System.Convert.ToInt32() will return 0 (i.e. the default for int).
  • int.Parse() has an overload where you can pass in the NumberStyles flags enum to specify how the string should be handled. System.Convert.ToInt32() does not have this overload.
  • System.Convert.ToInt32() has an overload where you can specify the number base of the string, i.e. base 2, 8, 10, or 16.

Available overloads on int:

public static int Parse(string s)
public static int Parse(string s, NumberStyles style)
public static int Parse(string s, IFormatProvider provider)
public static int Parse(string s, NumberStyles style, IFormatProvider provider)

Available overloads on System.Convert (for the input type string):

public static int ToInt32(string value)
public static int ToInt32(string value, IFormatProvider provider)
public static int ToInt32(string value, int fromBase)

Some other points for you:

  • If you don’t provide the IFormatProvider both int.Parse() and Sytem.Convert.ToInt32() will retrieve the format off the CurrentCulture.
  • If you do not specify the NumberStyles for int.Parse() it will simply use NumberStyles.Integer.
  • System.Convert.ToInt32(string) and System.Convert.ToInt32(string, IFormatProvider) both call int.Parse() to do the conversion, where as System.Convert.ToInt32(string, int) calls ParseNumber.StringToInt(). This is a static internal class so you will need to use Red Gate’s .NET Reflector if you want to see it. Something interesting about this call is that it makes an internal call to a method in the CLR to do the conversion.

Looking at the corresponding methods for conversion on the other types it appears they seem to work in a similar way, with the exception that System.Convert.ToDouble() and System.Convert.ToDecimal() do not provide an overload to specify the number base.

New features in .Net 3.5 – Automatic Properties

A very simple and awesome new feature in 3.5 is Automatic Properties, the basic idea is that you just define the property name and the visibility of the getter and setter. No need to specify the private field and the body of the get and set to retrieve and set the value. So the snippet below:

private EntityState _EntityState;
public EntityState EntityState
{
    get { return _EntityState; }
    private set { _EntityState = value; }
}

Would become:

public EntityState EntityState { get; private set; }

The 3.5 framework handles creating the getter, setter, and private member for you. This small addition to the framework can made your code much cleaner.

Obviously it only helps for those situations where you are just retrieving the value / setting it, if you want to do any additional processing you’ll need to create your property the old fashioned way.

Automatic properties must have get and set declared, which is obvious considering that the private member is not accessible, so all access must go through the property

Disclaimer: This post is based on Orcas CTP June 2007

New features in .Net 3.5 – Object Initializers

A new feature in the 3.5 framework is object initializers, object initializers allow you to set the values of public properties on an object in the constructor call. In the past you would have to create the instance of the object then assign each property one by one, for example:

_DataContext = new RdmDataContext();
_DataContext.LoadOptions = options;
_DataContext.DeferredLoadingEnabled = true;

Using the new syntax you can set the properties in a single statement:

_DataContext = new RdmDataContext() { LoadOptions = options, DeferredLoadingEnabled = true };

Much cleaner! Note that you can only set the values of public properties on the object.

Disclaimer: This post is based on Orcas CTP June 2007

LINQ to SQL – DataContext Load Options

The LINQ framework provide a simple (although not a mature) solution to eager loading data, namely the DataLoadOptions class. This class allows you to specify what related data should be retrieved when some data X is retrieved, for example you can tell the data context to load all related apartments when loading a building:

DataLoadOptions options = new System.Data.Linq.DataLoadOptions();
options.LoadWith<Building>(building => building.Apartments);
_DataContext = new RdmDataContext();
_DataContext.LoadOptions = options;

This is great, whenever you request a building LINQ will automatically retrieve all the related apartments, there are some negatives to this though, so you need to think through your load options carefully.

Using the data load options above, if you request a list of buildings off the data context LINQ will hit the database just once to retrieve all the buildings and apartments so you will get the duplicate building information retrived for each apartment. Now this doesn’t affect your LINQ entities but it does mean you are retrieving more data than is needed. It would be nice if the guys at Microsoft could change the eager loading to first retrieve all the buildings and then a seperate query to retrieve all the related apartments.

You can’t request eager loading for more than one level in a single statement, so the statement below would not work:

options.LoadWith<Apartment>(apartment => apartment.CurrentLease.PrimaryTenant);

You need to break it into two statements:

options.LoadWith<Apartment>(apartment => apartment.CurrentLease);
options.LoadWith<Lease>(lease => lease.PrimaryTenant);

If you have a scenario where some object has a collection of objects, and each of those objects has some collection of objects you can’t eager load it all at once. You’d think that the statement below would load all apartments and leases when you retrieve a building, but it doesn’t.

options.LoadWith<Building>(building => building.Apartments);
options.LoadWith<Apartment>(apartment => apartment.Leases);

This will retrieve the leases on the apartment as needed, i.e. lazy load. I’m not sure if this is a bug or a deliberate limitation, I haven’t been able to find any information on the issue.

Adding a calculated property to the data load options will be ignored so don’t bother, i.e. a property that is not mapped to a database field.

The last important item to note is that you need to assign the load options to the data context before requesting any data, and you can’t change the load options after requesting data from the data context. This is the biggest downside of the data load options.

Disclaimer: This post is based on Orcas CTP June 2007