問題起源於微軟官方論壇中的一個文章,他給出了一段VB.NET編寫的代碼:
Dim stralltext As String = My.Computer.FileSystem.ReadAllText("c:\magic.txt")
Dim StrLines() As String = stralltext.Split(ControlChars.CrLf)
大家看第二行的Split方法調用,ControlChars.CrLf是一個string類型,而Split方法的重載中並沒有第一個參數是string類型的重載實現,由於平時寫C#代碼比較多,而對VB.NET瞭解比較少,我想當然的認為這段代碼不能通過編譯,實際上在C#中編寫類似的代碼會出現如下兩個編譯錯誤:
錯誤 1 與“string.Split(params char[])”最匹配的重載方法具有一些無效參數
錯誤 2 參數“1”: 無法從“string”轉換為“char[]”
我重新用VB.NET的編譯器來編譯這段代碼,VB編譯器的行為的確有些出乎我的預料!,居然成功通過了編譯,我的直覺告訴我應該是VB.NET的編譯器把 string轉換成char數組了,大家看產生的IL代碼:
.method public static void Main() cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// 代碼大小 44 (0x2c)
.maxstack 4
.locals init ([0] string stralltext,
[1] string[] StrLines,
[2] char[] VB$t_array$S0)
IL_0000: nop
IL_0001: call class ConsoleApplication1.My.MyComputer ConsoleApplication1.My.MyProject::get_Computer()
IL_0006: callvirt instance class [Microsoft.VisualBasic]Microsoft.VisualBasic.MyServices.FileSystemProxy [Microsoft.VisualBasic]Microsoft.VisualBasic.Devices.ServerComputer::get_FileSystem()
IL_000b: ldstr "c:\\magic.txt"
IL_0010: callvirt instance string [Microsoft.VisualBasic]Microsoft.VisualBasic.MyServices.FileSystemProxy::ReadAllText(string)
IL_0015: stloc.0
IL_0016: ldloc.0
IL_0017: ldc.i4.1
IL_0018: newarr [mscorlib]System.Char //這裡VB編譯器自動構造了一個Char數組
IL_001d: stloc.2
IL_001e: ldloc.2
IL_001f: ldc.i4.0
IL_0020: ldc.i4.s 97
IL_0022: stelem.i2
IL_0023: ldloc.2
IL_0024: callvirt instance string[] [mscorlib]System.String::Split(char[]) //這裡調用的是String.Split(char[])這個重載
IL_0029: stloc.1
IL_002a: nop
IL_002b: ret
} // end of method Module1::Main
這段IL代碼證明了我一開始的推斷,VB.NET編譯器的確是構造了一個char數組,這一行為和C#編譯器有一定的區別,C#編譯器並不會隱式的把string轉換成char[]。
可能VB.NET程式員對這個現象已經十分的熟悉了(不要見笑啊!我對VB.NET編譯器不是很瞭解啊),但是C#中並不能這樣使用,為了不在語言互操作的時候令C#程式員產生疑惑,還是衷心的希望VB.NET程式員可以顯式的構造Char數組啊!