格式化DataRow.Item时抛出System.InvalidCastException的原因?
DataRow.Item调用ToString("N0")抛出InvalidCastException的原因及解决
环境
VS 2022 Community 17.5.3,控制台应用
问题代码
Module Module1 Sub Main() Dim DT1 As DataTable = New DataTable("DT1") ' 为DataTable添加列 Dim FieldType As Type = GetType(System.Int64) Dim MyColumn As DataColumn = New DataColumn("Col1", FieldType) DT1.Columns.Add(MyColumn) ' 添加行并赋值 Dim NewRow As DataRow = DT1.NewRow Dim RowArray() As Object = New Object() {1234} NewRow.ItemArray = RowArray DT1.Rows.Add(NewRow) ' 显示行中Col1的格式化值 Console.WriteLine("Col1 Value = " & NewRow.Item("Col1")) Console.WriteLine("Col1 Type = " & NewRow.Item("Col1").GetType.ToString) Console.WriteLine("Col1 Formatted Value = " & NewRow.Item("Col1").ToString("N0")) End Sub End Module
输出及异常
执行输出
Col1 Value = 1234 Col1 Type = System.Int64
异常信息
System.InvalidCastException HResult=0x80004002 Message=Conversion from string "N0" to type 'Integer' is not valid. Source=Microsoft.VisualBasic StackTrace: at Microsoft.VisualBasic.CompilerServices.Conversions.ToInteger(String Value) in f:\dd\vb\runtime\msvbalib\Helpers\Conversions.vb:line 788 at ConsoleTest.Module1.Main() in C:\Data\VB.NET\ConsoleTest\ConsoleTest\Module1.vb:line 1434 This exception was originally thrown at this call stack: Microsoft.VisualBasic.CompilerServices.Conversions.ParseDouble(String, System.Globalization.NumberFormatInfo) in Conversions.vb Microsoft.VisualBasic.CompilerServices.Conversions.ParseDouble(String) in Conversions.vb Microsoft.VisualBasic.CompilerServices.Conversions.ToInteger(String) in Conversions.vb Inner Exception 1: FormatException: Input string was not in a correct format.
原因分析
核心问题在于**NewRow.Item("Col1")返回的是Object类型**:
- 编译阶段,编译器只能识别
Object自带的无参数ToString()方法,无法直接调用Int64实现的ToString(String)重载(该重载来自IFormattable接口)。 - VB.NET编译器会将
Object.ToString("N0")误解析为调用全局的Microsoft.VisualBasic.Strings.ToString函数,这个函数的重载要求传入Integer类型参数,因此会尝试将字符串"N0"转换为整数,转换失败后抛出InvalidCastException。
而当你先将NewRow.Item("Col1")转换为Int64变量后,编译时类型明确为Int64,编译器会正确匹配Int64.ToString(String)重载,自然能生成格式化后的结果。
解决办法
方法1:显式转换为Int64后调用ToString
' 使用CType转换 Console.WriteLine("Col1 Formatted Value = " & CType(NewRow.Item("Col1"), Int64).ToString("N0")) ' 或使用DirectCast转换 Console.WriteLine("Col1 Formatted Value = " & DirectCast(NewRow.Item("Col1"), Int64).ToString("N0"))
方法2:使用String.Format自动处理格式化
Console.WriteLine("Col1 Formatted Value = " & String.Format("{0:N0}", NewRow.Item("Col1")))
内容的提问来源于stack exchange,提问作者BandannaMan
相关产品推荐
相关产品推荐

