NotCloseToFour NotCloseToFour - 1 year ago 58 Question

Behind the scenes of Visual Basic casting - Conversion from string to type 'Double' is not valid

While playing around doing string concatenation in, I noticed a weird runtime error when trying to concatenate a string with an integer.

Here is my fiddle:

Imports System
Imports System.Collections.Generic

Public Module Module1
Public Sub Main()
Dim t As Dictionary(Of Int32, DateTime?) = new Dictionary(Of Int32, DateTime?)
t.Add(12345, new DateTime())
For Each f As KeyValuePair(Of Int32, DateTime?) In t
Console.WriteLine("Test string {" + f.Key + "}.")
End Sub
End Module

Specifically, I'm curious why the exception:

System.InvalidCastException: Conversion from string "Test string {" to type 'Double' is not valid.

is occurring. I know that this is a simple fix if I explicitly convert the integer to a string:

Console.WriteLine("Test string {" + f.Key.ToString() + "}.")

I'm just curious what is happening behind the scenes that this casting error would occur. I am not touching doubles anywhere in my code, so I am unsure why a casting to type 'Double' would be the problem being thrown.

Answer Source

The + operator in VB is a complex beast. It can do very different things depending on its operands. In your case, it's following the 3rd row in that table:

One expression is a numeric data type and the other is a string


If Option Strict is On, then generate a compiler error.

If Option Strict is Off, then implicitly convert the String to Double and add.

If the String cannot be converted to Double, then throw an InvalidCastException exception.

It looks like Option Strict must be Off in your code, so it is indeed attempting to convert the String to a Double, and hence erroring.

Ideally, always use Option Strict On (and Option Explicit On - they're usually the first thing I check when I'm working with VB) - it will show up all sorts of potential runtime issues at compile time instead.

Also, if you want to guarantee string concatenation, Option Strict or not, you can use the & operator.