Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper time to cast vs. convert in c#

Tags:

c#

casting

So I've always assumed that casting and converting in c# are basically the same thing: Two different ways to go from one data type to another. Clearly this is incorrect though since they often will output different results.

Convert.ToInt32(1.6)     //outputs 2
(Int32)1.6               //outputs 1


(DateTime)("10/29/2013")          //won't compile - cannot convert type 'string' to type 'system.date.time'
Convert.ToDateTime("10/29/2013")  //outputs 10/29/2013 12:00:00 AM
  • My question is what is the primary difference between the two and why do they return different results?
  • What is the 'appropriate' time to use one over the other?

Personally I find myself using the Convert.To method as that seems cleaner to me. I know that it also throws the System.InvalidCastException. Can anyone provide a straightforward explanation?

like image 305
ovaltein Avatar asked Oct 29 '13 15:10

ovaltein


Video Answer


2 Answers

You can use cast in two cases:

  • when type you are casting to IS a type you are casting from
  • when explicit cast operator defined for these types

In all other cases you should use Convert or other custom conversion method (e.g. DateTime.Parse).

why do they return different results?

Because different code is executed. Convert.ToInt32(double value) rounds result of casting:

int num = (int) value;
double num2 = value - num;
if ((num2 > 0.5) || ((num2 == 0.5) && ((num & 1) != 0)))    
    num++;

return num;
like image 151
Sergey Berezovskiy Avatar answered Nov 02 '22 01:11

Sergey Berezovskiy


In your conversion the Convert.ToInt32 method uses the following rules for its return value

value, rounded to the nearest 32-bit signed integer. If value is halfway between two whole numbers, the even number is returned; that is, 4.5 is converted to 4, and 5.5 is converted to 6.

However the rules for the explicit conversion are different

When you convert a decimal value to an integral type, this value is rounded towards zero to the nearest integral value. If the resulting integral value is outside the range of the destination type, an OverflowException is thrown.

If you want the cast to operate the same as the Convert.ToInt32 [or want to specify how the rounding would work] then you should use the Math.Round method with a cast as follows.

(int)Math.Round(1.6) //outputs 2

There are other method signatures which allow you to specify how to Round as well.

As far as when you should use cast and convert, you should use the explicit cast when possible realizing that you are going to lose precision when going from a more precise to less precise type and handling it appropriately and the convert when the data is not expected to be in a format that can be cast. when possible means when explicit conversion (including implicit conversions) exists. The pre-defined conversions can be found in Section 6 of the spec

A cast-expression of the form (T)E, where T is a type and E is a unary-expression, performs an explicit conversion (Section 6.2) of the value of E to type T. If no explicit conversion exists from the type of E to T, a compile-time error occurs. Otherwise, the result is the value produced by the explicit conversion.

like image 26
Harrison Avatar answered Nov 02 '22 03:11

Harrison