Casting vs. Converting in .Net

I recently saw a piece of code in a project that was throwing an exception that I did not understand:

string boolString = (string)DataBinder.Eval(DataItem, "IsNew");

One would expect that boolString would be assigned the value “True” or “False” depending on the value of the IsNew property of the DataItem object. However, this through an Exception with the message: “Cannot explicitly convert bool to string”. What is going on here?

The syntax of (type)variable attempts to explicitly cast the variable into the given type. Casting does not attempt to interpret the data in the variable – it just tries to fit the object referred to by the variable into the new data type. This will work whenever the two types are somehow compatible (for example, an int can be cast into a float with no exceptions) though sometimes it may result in data loss (a float cast into an int). However, in cases where there is no connection between the two classes, casting will result in an Exception (like the one that I received above).

(There is another way to cast an object – using the as keyword. This will return a null if the cast fails, and is much faster than the explicit casting referred to above).

However, when converting an object, the conversion function has “knowledge” of the data contained in both the source and final object types, and will create the equivalent of the variable in the new data type. In the case above, using the System.Convert.ToString() method in place of the attempted cast to (string) would have worked fine. This is because the ToString method “knows” that a bool cannot be case into a string – but it also knows what the equivalent string to each value of a bool will be, and is able to process the operation accordingly. In this case, reflector uncovers the following code (in the Boolean class):

public string ToString() {
    if (!this) {
        return "False";
    }
    return "True";
}

This is obviously a very simple type conversion. However, there are many more complex conversion utilities built into the .Net framework (accessible through the System.Convert class – see the DateTime.ToString conversion for an example of this. Also see the IConvertible interface). While conversions can be more expensive to run, since they are strongly typed, they are checked at compile time, and when used properly are more reliable to use when producing stable code. (See the MSDN article on Casting and Type Conversions for more info).