views:

209

answers:

3

I had until recently been under the impression that the CDbl(x) operation in VB.NET was essentially a cast (i.e., the VB equivalent of (double)x in C#); but a recent discovery has revealed that this is not the case.

If I have this string:

Dim s As String = "12345.12345-"

And I do this:

Dim d As Double = CDbl(s)

d will be set to the value -12345.12345! Now, don't get me wrong, this is kind of convenient in my particular scenario; but I have to admit I'm confused as to why this works. In particular, I'm confused because:

  • Double.Parse does not work with the above input.
  • Double.TryParse does not work.
  • Convert.ToDouble does not work.

How is CDbl so clever?

A: 

If you go into Regional Options in Control Panel, there's a setting that let's you put the minus sign after, instead of before, numbers.

I'm not sure what system uses a minus sign after numbers, but it seems CDbl is programmed to accept both. Be liberal in what you accept, and all that.

Regional Options also has a setting for negative numbers where they are in brackets. Does that work? -- CDbl("(12345.12345)")

Chris Burt-Brown
+1  A: 

That's always been the the behavior of CDbl() in VB4/5/6 and is currently specific to VB.net (its inline, not part of the framework) so its probably just been kept for people moving from earlier versions.

(Much like weirdness in pre .net VB due to features bought over from QBasic)

Alex K.
+5  A: 

It uses Microsoft.VisualBasic.CompilerServices.Conversions.ToDouble(). That function contains a Select statement on the object's GetTypeCode() return value so it can use a custom converter based on the type of the argument. The string converter considers the possibility that the string might contain a currency value and does some processing on the string to deal with that. One allowed format for currency values is a trailing negative sign.

This is not particularly cheap. The quickest way to achieve the same conversion is:

Dim s As String = "12345.12345-"
Dim d As Double = Double.Parse(s, Globalization.NumberStyles.Any)
Hans Passant
Thanks for the in depth answer. As a VB6 programmer that converted to .NET, I've always tried to do things "the .NET way" instead of using the old vb function way. For example: .substring instead of Left, Mid, Right, .ToLower instead of LCase etc.
Jeremy