通过string.Split,方法,谈谈VB.NET编译器和C#编译器的一点差别!

问题起源于微软官方论坛中的一个帖子,他给出了一段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数组啊!