VB.Net中模塊定義的過(guò)程的默認(rèn)訪問(wèn)級(jí)別是Public
創(chuàng)新互聯(lián)始終堅(jiān)持【策劃先行,效果至上】的經(jīng)營(yíng)理念,通過(guò)多達(dá)十年累計(jì)超上千家客戶的網(wǎng)站建設(shè)總結(jié)了一套系統(tǒng)有效的營(yíng)銷解決方案,現(xiàn)已廣泛運(yùn)用于各行各業(yè)的客戶,其中包括:成都白烏魚(yú)等企業(yè),備受客戶贊賞。
你可以使用ILDasm反匯編一個(gè)VB.Net程序來(lái)查看
我進(jìn)行試驗(yàn)的源代碼為(Console Application):
Module Module1
Sub Main()
k()
End Sub
Sub k()
Console.WriteLine("ABC")
Console.ReadLine()
End Sub
End Module
使用ILDasm進(jìn)行反編譯后
k()過(guò)程被解釋為:
.method public static void k() cil managed
{
// 代碼大小 20 (0x14)
.maxstack 8
IL_0000: nop
IL_0001: ldstr bytearray (C8 54 C8 54 ) // .T.T
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: call string [mscorlib]System.Console::ReadLine()
IL_0011: pop
IL_0012: nop
IL_0013: ret
} // end of method Module1::k
由此得知,在VB.NET的模塊中定義的過(guò)程的默認(rèn)訪問(wèn)級(jí)別是Public,而不是Friend
如果你在循環(huán)中定義的是值類型變量(如Integer、String等系統(tǒng)預(yù)定義的基本類型,以及用Structure定義的任何類型,如Point),那么是不會(huì)在循環(huán)的過(guò)程中不斷地進(jìn)行創(chuàng)建和銷毀,這個(gè)要在ILDASM中看才會(huì)看到。你之所以在VB.NET中看到變量在循環(huán)外面就不見(jiàn)了,那是IDE在作怪,它根據(jù)調(diào)試信息屏蔽掉了。事實(shí)上這個(gè)變量在進(jìn)入函數(shù)的時(shí)候就給你創(chuàng)建好了,并且在推出函數(shù)的時(shí)候才會(huì)被注銷掉。
當(dāng)然,以上的情況不包括用Class定義的所有類。例如Form、Control等。
建立這樣一個(gè)ConsoleApplication,在Sub Main里面添加代碼如下:
Public Sub Main()
Dim i As Integer
For i = 1 To 10
Dim s As String
s = i.ToString()
Next
End Sub
編譯成Exe,然后執(zhí)行VS.NET\Framework SDK\bin\目錄下的ILDASM.EXE,用它打開(kāi)編譯好的EXE文件,找到Module1,雙擊Main:void(),就可以看到中間代碼了——一種所謂IL的偽匯編。
再來(lái)給大家解釋一下吧:
// method表示是“方法”,實(shí)際上就是函數(shù)。
// public和VB中的沒(méi)區(qū)別,static表示是Shared的,void表示無(wú)返回值,cil表示是符合CIL的,managed 托管的。
method public static void Main() cil managed
{
.entrypoint //表示這里是整個(gè)程序的入口點(diǎn)。
//下面這個(gè)是一個(gè)標(biāo)記,用于表示這個(gè)函數(shù)是單線程的。
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size 23 (0x17)
.maxstack 2 //表示本地變量所需要的堆棧大小,2*4Bytes
.locals init ([0] int32 i, // init是初始化的意思,第0號(hào)整型本地變量i
[1] string s) // 第1號(hào)字符串變量s
IL_0000: nop // 空指令
IL_0001: ldc.i4.1 // 將整數(shù)(i4表示整數(shù))1裝入堆棧
IL_0002: stloc.0 // 將頂上的堆棧彈到第0號(hào)本地變量,也就是i中。
// 上面兩句的意思是 (For) i = 1
IL_0003: ldloca.s i // 將本地變量i裝到堆棧頂上。
//調(diào)用實(shí)例化(instance)的Int32.ToString()。(所有的返回值都在堆棧頂端)
IL_0005: call instance string [mscorlib]System.Int32::ToString()
IL_000a: stloc.1 // 將棧頂元素推到第1號(hào)本地變量,也就是s中。
//上面三句的意思是 s = i.ToString()
IL_000b: nop
IL_000c: ldloc.0 // 將i推到棧頂。
IL_000d: ldc.i4.1 // 將整數(shù)1推到棧頂。
IL_000e: add.ovf // 將堆棧最頂上的兩個(gè)元素相加,并進(jìn)行溢出檢查。
IL_000f: stloc.0 // 將相加的結(jié)果(在棧頂)推到i中。
//上面三句的意思是 i = i 1
IL_0010: ldloc.0 // 將i推到棧頂
IL_0011: ldc.i4.s 10 // 將整數(shù)10推到棧頂。
IL_0013: ble.s IL_0003// 如果最頂上的兩個(gè)元素中先入棧的小于等于后入棧的,
// 那就跳轉(zhuǎn)到IL_0003
// 上面三句話的意思是 For (i=1) To 10 ... Next
IL_0015: nop
IL_0016: ret // 返回
} // end of method Module1::Main
于是,在整個(gè)循環(huán)過(guò)程中,只有最開(kāi)始時(shí)有一個(gè)對(duì)s的初始化,其他地方就沒(méi)有見(jiàn)到了,甚至沒(méi)有看到顯式的“注銷”。這下子不用擔(dān)心寫(xiě)在里面會(huì)降低效率了。
在VB.NET里,給變量賦值NoThing,其結(jié)果將對(duì)該變量賦予初始值;
而對(duì)于字符串變量初始值就是“”,數(shù)值變量初始值為0,布爾變量初始值為False。
所以對(duì)于字符串變量,賦予NoThing與賦予""是相同的。