19

A question cropped up at work today about how to convert an object into its specific type (an int), I said to cast it:

int i = (int)object;

a colleague said to use Convert.ToInt32().

int i = Convert.ToInt32(object)

What's the difference between Convert.ToInt32() and a direct object cast?

George Stocker
  • 57,289
  • 29
  • 176
  • 237
m.edmondson
  • 30,382
  • 27
  • 123
  • 206

8 Answers8

17

Not every object can be cast directly to int. For example, the following will not compile:

string s = "1";
int i = (int)s;

because string is not implicitly convertible to int.

However, this is legal:

string s = "1";
int i = Convert.ToInt32(s);

As a side note, both casting and Convert can throw exceptions if the input object cannot be converted. However, int.TryParse does not throw if it fails; rather, it returns false (but it only takes in a string, so you have to .ToString() your input object before using it):

object s = "1";
int i;
if(int.TryParse(s.ToString(), out i))
{
   // i now has a value of 1
}
Mark Avenius
  • 13,679
  • 6
  • 42
  • 50
  • The word you're looking for is "explicitly" in the second "paragraph" -- implicit would be `int i = s`. – Nic Jan 08 '17 at 23:57
11

They are fundamentally different

Casting says that the object is an instance of the type being cast to, so cast it.

Convert says that there is a conversion between the types being converted.

So for example you can't cast a string to an int, but you can convert it. There is some grey area/overlap due to certain built in cast rules for primitive types, or explicit cast conversions you can add to your own types. But generally I wouldn't think of these two as the equivalent.

Given that there is no 'better' option, you should use the option that makes sense in the given context.

James Gaunt
  • 14,631
  • 2
  • 39
  • 57
  • 11
    I think it's a matter of intent. Casting clearly says "I know you're an `int`!" whereas Convert says "I have no idea what you are, but eventually I know you'll be an `int`" – Greg Feb 09 '11 at 16:49
  • Yes - very nice way of explaining it - thanks. – James Gaunt Feb 09 '11 at 17:00
1

You can only cast when the original type has a cast defined for the new type. So casting from one numeric type to another (e.g. long to int) is normally possible but casting from non-numeric types to numeric types (e.g. string to int) normally is not possible. Convert provides many more methods to change these non-numeric types to numeric, so the reason to use it is you are less likely to get an error.

Charles Boyung
  • 2,464
  • 1
  • 21
  • 31
1

I tend to prefer Convert myself just because it provides a nice uniform interface to conversion. For example Convert.ToInt32("45") works but (int)"45", does not.

Convert will also report issues such as throwing an OverflowException. Casting can be dangerous as casting from say long to an int could yield a poor result and the runtime won't tell you.

I also like that Convert.ToX(object obj) exists, which lets you just fire things off to Convert and for the most part forget about it.

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
  • 2
    On your second statement; what you said is true in the default case, but you could wrap the cast in a "checked" block, which will throw an ArithmeticOverflowException in such cases. – KeithS Feb 09 '11 at 16:35
1

Convert.ToInt32 is basically the same as int.Parse With one difference: if you use int.Parse(null) an exception is thrown, while Convert.ToInt32 returns 0

Casting on the other hand is a more complex operation and will only work if the value really is a boxed int or anohter (boxed/unboxed) value type that can be implicitly converted.

(boxing is an object representation of a value type)

Simon Smeets
  • 581
  • 6
  • 17
1

Convert is a class that contains a series of static methods and is suposed to be used to convert base types, the supported types are Boolean, Char, SByte, Byte, Int16, Int32, Int64, UInt16, UInt32, UInt64, Single, Double, Decimal, DateTime and String. The cast operator allows you to do the same thing but you can use it for other types as well, including the types you create. You also can define this operators in your classes, allowing you to convert from anything to anything. So thats the difference, one is a method and the other one is an operator, I have not checked the guts of the operaror when converting and int to a string, but it might have the same logic as the methods in Convert.

Oakcool
  • 1,470
  • 1
  • 15
  • 33
0

If you know that the boxed instance is an int, you can safely use the (int) cast operator to unbox it. However, if it's convertible to an int (e.g. a float), using the cast operator will fail at runtime.

Check out the Convert class documentation for more details on the specific conversions it allows and disallows.

Sasha Goldshtein
  • 3,499
  • 22
  • 35
0

The difference is Convert.ToInt32(object value) will try to use IConvertible to convert the value to int where as direct cast will simply throw an exception if such cast is not valid.

The other overloads also try converting and not casting.

Amy West
  • 163
  • 8
Jaroslav Jandek
  • 9,463
  • 1
  • 28
  • 30