我正在创建一个通用方法来将数组打印到分隔字符串,而 ToString() 方法的行为很奇怪。采取这个功能:
Public Function ToString(Of T)(array() As T, delimiter As String, format As String) As String
Dim resultBuilder As New StringBuilder
If array IsNot Nothing AndAlso array.Count > 0 Then
For i As Integer = 0 To array.Count - 1
If i Then resultBuilder.Append(delimiter)
resultBuilder.Append(array(i).ToString(format))
Next
End If
Return resultBuilder.ToString
End Function
并呈现它
Dim a() As Integer = {32, 14, 7, 0}
Label1.Text = ToString(a, ", ", "0000")
我希望函数返回
0032, 0014, 0007, 0000
函数正在返回
3, 1, 7, 0
我认为问题是 ToString() 函数很难知道它所应用的类型,但调试器敏锐地意识到
T
是 Integer
并且知道如何在 Watch 中正确格式化整数。不管是哪种类型,这种行为仍然是不寻常的。到底发生了什么事?
调试器的知识并不相关,因为调试器知道事物的运行时类型是什么,但重载选择是基于编译时类型的。请注意,对于泛型,编译时类型要么是
Object
,要么基于泛型定义中的任何约束;它不是实际的实例化类型。
据此,我们可以得出结论,正在调用的是
Object.ToString
(因为通用定义中对T
没有任何限制)。如果你转动Option Strict On
,你会得到一个关于无法将format
转换为Integer
的错误,这有点令人惊讶,因为据我所知,ToString
上只有一个零参数Object
。该错误可能是由于编译器感到困惑,或者可能是有一些可访问的 Object.ToString
版本,它采用单个 Integer
参数。