VB.Net中模块定义的过程的默认访问级别是Public
坚守“ 做人真诚 · 做事靠谱 · 口碑至上 · 高效敬业 ”的价值观,专业网站建设服务10余年为成都门帘小微创业公司专业提供企业网站设计营销网站建设商城网站建设手机网站建设小程序网站建设网站改版,从内容策划、视觉设计、底层架构、网页布局、功能开发迭代于一体的高端网站建设服务。
你可以使用ILDasm反汇编一个VB.Net程序来查看
我进行试验的源代码为(Console Application):
Module Module1
Sub Main()
k()
End Sub
Sub k()
Console.WriteLine("ABC")
Console.ReadLine()
End Sub
End Module
使用ILDasm进行反编译后
k()过程被解释为:
.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的模块中定义的过程的默认访问级别是Public,而不是Friend
isnothing : 检测变量值是否为nothing。nothing表示任意数据类型的默认值,如果变量是引用类型,则值 Nothing 意味着该变量不与任何对象相关联。
isdbnull:说明对象的数据丢失或不存在,用于指示缺少的值。它不等效于 nullNothing 或empty
null :一般用于数据库中。数据库中的字段可能需要区分已赋予一个有意义的值与尚未赋值这两种情况, 尚未赋值将用 null 值表示。
另外可以为 null 的类型的最重要成员是它有 HasValue 和 Value 属性。 HasValue 为 FALSE时
value为 null
empty: 表示尚未实例化的变量的值,string.empty是空字符串“”,
IsNullOrEmpty:判断是否为null或者empty.
在VB.NET里,给变量赋值NoThing,其结果将对该变量赋予初始值;
而对于字符串变量初始值就是“”,数值变量初始值为0,布尔变量初始值为False。
所以对于字符串变量,赋予NoThing与赋予""是相同的。
1、点击VS工具。
2、打开后,新建一个Windows窗体应用程序。
3、新建完毕后,如图所示。
4、拖动一个按钮。
5、定义数组最常见的方法,如图示。
6、运行后,点击按钮,弹出提示正常。
7、定义数组第二种方法,属于动态的方法。
8、运行后,点击按钮,数组成功输出。
如果你在循环中定义的是值类型变量(如Integer、String等系统预定义的基本类型,以及用Structure定义的任何类型,如Point),那么是不会在循环的过程中不断地进行创建和销毁,这个要在ILDASM中看才会看到。你之所以在VB.NET中看到变量在循环外面就不见了,那是IDE在作怪,它根据调试信息屏蔽掉了。事实上这个变量在进入函数的时候就给你创建好了,并且在推出函数的时候才会被注销掉。
当然,以上的情况不包括用Class定义的所有类。例如Form、Control等。
建立这样一个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,然后执行VS.NET\Framework SDK\bin\目录下的ILDASM.EXE,用它打开编译好的EXE文件,找到Module1,双击Main:void(),就可以看到中间代码了——一种所谓IL的伪汇编。
再来给大家解释一下吧:
// method表示是“方法”,实际上就是函数。
// public和VB中的没区别,static表示是Shared的,void表示无返回值,cil表示是符合CIL的,managed 托管的。
method public static void Main() cil managed
{
.entrypoint //表示这里是整个程序的入口点。
//下面这个是一个标记,用于表示这个函数是单线程的。
.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号整型本地变量i
[1] string s) // 第1号字符串变量s
IL_0000: nop // 空指令
IL_0001: ldc.i4.1 // 将整数(i4表示整数)1装入堆栈
IL_0002: stloc.0 // 将顶上的堆栈弹到第0号本地变量,也就是i中。
// 上面两句的意思是 (For) i = 1
IL_0003: ldloca.s i // 将本地变量i装到堆栈顶上。
//调用实例化(instance)的Int32.ToString()。(所有的返回值都在堆栈顶端)
IL_0005: call instance string [mscorlib]System.Int32::ToString()
IL_000a: stloc.1 // 将栈顶元素推到第1号本地变量,也就是s中。
//上面三句的意思是 s = i.ToString()
IL_000b: nop
IL_000c: ldloc.0 // 将i推到栈顶。
IL_000d: ldc.i4.1 // 将整数1推到栈顶。
IL_000e: add.ovf // 将堆栈最顶上的两个元素相加,并进行溢出检查。
IL_000f: stloc.0 // 将相加的结果(在栈顶)推到i中。
//上面三句的意思是 i = i 1
IL_0010: ldloc.0 // 将i推到栈顶
IL_0011: ldc.i4.s 10 // 将整数10推到栈顶。
IL_0013: ble.s IL_0003// 如果最顶上的两个元素中先入栈的小于等于后入栈的,
// 那就跳转到IL_0003
// 上面三句话的意思是 For (i=1) To 10 ... Next
IL_0015: nop
IL_0016: ret // 返回
} // end of method Module1::Main
于是,在整个循环过程中,只有最开始时有一个对s的初始化,其他地方就没有见到了,甚至没有看到显式的“注销”。这下子不用担心写在里面会降低效率了。