13

What, if any, is the difference between?

decimal d = (decimal) myDouble;
decimal d = new decimal(myDouble);
decimal d = Convert.ToDecimal(myDouble);
Darren
  • 68,902
  • 24
  • 138
  • 144
Adam A
  • 413
  • 7
  • 14

3 Answers3

10

There is no difference. If you look at the source:

In Decimal:

public static explicit operator decimal(double value)
{
    return new decimal(value);
}    

In Convert:

public static decimal ToDecimal(float value)
{
    return (decimal) value;
}

So in the end they all call new decimal(double).

MgSam
  • 12,139
  • 19
  • 64
  • 95
  • But there might be a difference between `(decimal)value` and `new decimal(value)`: the first invokes the built-in double-to-decimal conversion operator, while the second invokes an overload of the decimal constructor. Granted, the native code will probably be the same, but the IL is probably different, and the C# semantics are certainly different. – phoog May 11 '12 at 14:51
  • 2
    @phoog There is no difference between the two. There is no "built-in" double-to-decimal conversion operator, the first method provided in the answer is the one that is called. The first way you provided just calls the second way you provided one method down the call tree. – JKor May 11 '12 at 14:55
  • @JKor I didn't provide any ways; I'm just commenting. – phoog May 11 '12 at 14:57
  • 1
    @phoog Yes you did, you provided `(decimal)value` and `new decimal(value)`. – JKor May 11 '12 at 14:58
  • @JKor ah, sorry, I misunderstood. Anyway, if there is no "built-in" double-to-decimal conversion, then please explain this IL: `call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Explicit(float64)` The constructor example compiles to this: `call instance void [mscorlib]System.Decimal::.ctor(float64)` These ultimately compile to *different* `internalcall` methods in the runtime. – phoog May 11 '12 at 15:10
  • But if you look, the op_Explicit(float64) method calls the constructor, as shown above. (`public static explicit operator aType` compiles to a method named `op_Explicit(aType)`) – JKor May 11 '12 at 22:54
5

They all achieve the same results. However, here's a more broken down explanation:

  • Method 1 creates a new variable which explicitly casts myDouble to type decimal. When you cast, you're saying, "This object of type A is really an object of type B-derived-from-A or a casting operator exists to cast A to B."

  • Method 2 creates a new variable which will convert myDouble to the appropriate type (decimal) via a constructor overload. When you invoke a constructor, you're saying, "Create a new object based on the arguments passed into the constructor."

  • Method 3 converts a base data type (double) to another base data type (decimal). When you use something like Convert.ToDecimal(), you're saying, "This object isn't of type B, but there exists a way to make it into an object of type B."

Regarding Convert MSDN states:

  • A conversion method exists to convert every base type to every other base type. However, the actual conversion operation performed falls into three categories:

  • A conversion from a type to itself simply returns that type. No conversion is actually performed.

  • A conversion which cannot yield a meaningful result throws InvalidCastException. No conversion is actually performed. An exception is thrown for conversions from Char to Boolean, Single, Double, Decimal or DateTime, and from those types to Char. An exception is thrown for conversions from DateTime to any type except String, and from any type, except String, to DateTime. Any base type, other than those described above, can be converted to and from any other base type.
Darren
  • 68,902
  • 24
  • 138
  • 144
  • Example 2 shows a constructor overload. Also, the cast example in example 1 is not a cast according to your definition, because of course decimal does not derive from double (nor the other way around). Rather, the C# cast operator has two functions: (1) representation-preserving type casting of reference types and (2) invoking built-in or user-defined explicit (or implicit) conversions. – phoog May 11 '12 at 14:47
3

There is not any difference, actually, from functional point of view. These are different ways to achieve the same result.

Important to mantion that in case of Convert.ToDecimal, you have a possibility to specify a format IFormatProvider(culture), so you gain more flexibility.

If you don't care about multiculture environment, pick any of them you like.

Tigran
  • 61,654
  • 8
  • 86
  • 123