189 8069 5689

vb.net从元数据的简单介绍

vb6.0和vb.net有什么区别?

VB6.0是基于对象的,VB.NET是面向对象的,它们之间的语法上差距还是比较大的.

成都网站制作、网站建设介绍好的网站是理念、设计和技术的结合。创新互联拥有的网站设计理念、多方位的设计风格、经验丰富的设计团队。提供PC端+手机端网站建设,用营销思维进行网站设计、采用先进技术开源代码、注重用户体验与SEO基础,将技术与创意整合到网站之中,以契合客户的方式做到创意性的视觉化效果。

VB.NET生成的是托管代码,必须运行于.NET框架之上.VB6则依赖于VB6运行时的支持.

在WINDOWS的下一版本WINDOWS 7中仍然会提供VB6的支持,不过再到以后的版本就没了.

如果你是第一次学,个人觉得还是直接转向VB.NET学习好了.

VB .NET编程是否可以不依赖.NET Framework

这是典型对.net构架不理解造成的!

只要是.net编程,一定使用的是.net类库,必须是同运行版本的.net支持方可运行。而所谓的vb.net只是说编程的语言层使用的是vb语言而已。该语言在.net构架下被编译成为IL语言(MSIL,严格说来是IL的一个子集)。而上层的语言只是产生软件时所使用的一个不同语言规则而已,与IL已经没有任何相关性了。上层语言无论是C#还是VB,甚至是Java(J#)均只适应编程人员的一个策略,与整个构造没有多大的相关性。

.net的最终目的就是让不同的语言编程人员能协同工作,那么语言在其中的区别没有多大了,所有的运行核心都是由.net完成的,没有必须依赖于.net。这是没有任何疑问的。

vb.net就是.net,只是表示用VB语言人的称呼,用C#的则称其为C#.net,但不管是哪种,它是无法脱离.net的。

vb和vb.net的区别

VB.NET和VB6.0有什么区别

Visual Basic .NET是Microsoft Visual Studio .NET套件中主要组成部分之一。.NET版本的Visual Basic增加了更多特性,而且演化为完全面向对象(就像C++)的编程语言。本文将介绍VB.NET的新特性,并比较VB6.0/VB.NET之间的区别,阐述如何利用VB.NET编写简单的应用程序。

1.1 什么是 VB.NET? Microsoft推出全新的编程和操作系统Framework——.NET,支持多种语言利用公共.NET库开发应用程序,这些应用程序在.NET Framework上运行。使用Visual Basic在.NET Framework上编程,这就是VB.NET。

首先,让我演示在VB.NET中写最简单的控制台程序:Hello World。

1.2 Hello, World!“Hello World!”是初学者学习Windows编程的代表性程序。我们的第一个程序就叫做“Hello VB.NET World!”。该程序在控制台输出一句话:“Hello VB.NET World!”,代码如下所示:

代码 1.1: Hello VB.NET World例子Imports System

Module Module1

Sub Main()

System.Console.WriteLine("Hello VB.NET World!")

End Sub

End Module

1.3 VB.NET 编辑器和编译器你可以在记事本或VS.NET IDE等任意文本编辑器中撰写上述代码,然后保存为HelloWorld.vb。 代码编写完成之后,要么在命令行、要么在VS.NET IDE中编译它。在Microsoft .NET Framework SDK中已经包括VB.NET编译器vbc.exe[][1],从IDE或是命令行都可以调用。要从命令行编译HelloWorld.vb,请在命令行窗口输入

vbc HelloWorld.vb /out:HelloWorld.exe /t:exe

编译结束后,HelloWorld.exe被创建到当前目录下。在资源管理其中双击图标或在命令行执行,程序正确地运行了。祝贺你进入VB.NET开发者的行列。

Imports 语句

如你所知,大部分的.NET类型都在名字空间(namespace)中定义。Namespace是定义和管理类别的范畴。察看.NET Framework Class Library,可以看到数以百计的namespace。例如,System namespace就包括了Console、Object等类型定义。如果想使用Console类,需要用Imports指令导入System namespace。如下所示:

Imports System甚至可以明确地调用namespace而无需用Import导入。下面的例子展示了不用Import的“Hello World!”程序:

代码1.2: Hello VB.NET World例子Module Module1

Sub Main()

System.Console.WriteLine("Hello VB.NET World!")

End SubEnd Module1.4 解析 "Hello VB.NET World!"程序第一行是:

Imports System; System namespace定义了Console类,该类用于读写控制台(命令行窗口)。然后你定义了一个module:Module Module1

…End Module所有的VB程序都包括一个Main()方法,即应用程序入口点。在例子程序中,我们调用Console.WriteLine()向控制台写入“Hello VB.NET World!”:

Sub Main()

Console.WriteLine(“Hello VB.NET World!”) End SubWriteLine()方法归属于Console类,它负责向控制台写一个带有行结束符的字符串。如前所述,Console类定义于System namespace,你通过直接引用来控制类成员。

Console类负责读写系统控制台。读控制台输入用Read和ReadLine方法,向控制台输出用WriteLine方法。

表1.1 Console类定义的方法

方法 用途 例子

Read 读入单个字符 int i = Console.Read();

ReadLine 读入一行 string str = Console.ReadLine();

Write 写一行 Console.Write("Write: 1");

WriteLine 写一行,并带上行结束符

Console.WriteLine("Test Output Data with Line");

1.5 VB.NET有什么新特点? VB.NET比 VB6.0更加稳定,而且完全面向对象。也许你还记得,VB6.0不支持继承、重载和接口,所以不是真正面向对象的。而VB.NET则支持这些面向对象特性。VB6.0有两个薄弱环节——多线程和异常处理。在VB.NET中,开发多线程应用和使用C++/C#别无二致,结构化异常处理也得到支持。稍后我们会详细解释这些特性。

下面是VB.NET的特性列表——

·面向对象的编程语言。支持继承、重载、接口、共享成员和构造器。·支持所有的CLS特性,如存取控制.NET类、与其它.NET语言交互、元数据、公共数据类型、委托等等。·多线程支持。·结构化异常处理。 1.6 名字空间与集合 前面讨论了我们的第一个VB.NET程序。该程序中首先引人注意的是名字空间(namespace)。在.NET参考文档中,你会发现每个类都归属于某个namespace。那么,namespace到底是什么?

一个namespace是类和组件的逻辑组合,其目的在于将.NET class按类别定义。微软借用了C++ class packaging概念:namespace来描述这种组合。.NET Framework中的组件被称为集合(assembly)。全部.NET代码在数百个库文件(DLL)中定义。Namespace把assembly中定义的类组织起来。一个namespace可以包括多个assembly,一个assembly也可以在多个namespace中定义。 namespace树的根节点是System namespace。在.NET Library中,每个class都在一组相似的类别中定义。例如,System.Data namespace只包括数据相关类。同样,System.Multithreading只包括多线程类。

在使用.NET支持的语言(如C#、VB.NET、C++.NET等)创建新应用程序时,你会注意到每个应用程序都被定义为一个namespace,而所有的class都归属于这个namespace。通过引用这个namespace,其它应用程序就能存取这些class。 在.NET中,代码被编译为中间语言(Intermediate Language,IL),assembly中存储了IL代码、元数据和其它资源文件。同一个assembly可以附属于一个或多个Exe/DLL。所有的.NET库都存储在assembly中。

1.7 VB.NET: 完全面向对象的编程语言抽象、封装、多态、继承是面向对象语言的四个基本属性。VB6.0不支持继承,而VB.NET则不然。所以,和C++一样,VB.NET也是完全面向对象的编程语言。

Class 和 ModuleVB.NET用Class...End Class语句对创建class。每个VB.NET至少包括一个Module(模块)。Module在Module…End Module语句对中实现。应用程序的主要模块是Main方法,亦即应用程序入口点。

和VB6.0相似的地方是,都可以使用Function/Sub关键字定义方法。下面的例子显示了如何创建class、添加方法,并从主程序调用方法: Imports System

Module Module1

Sub Main()

Dim cls As TestClass = New TestClass

Console.WriteLine(cls.MyMethod)

End Sub

Class TestClass

Function MyMethod() As String

Return "Test Method"

End Function

End Class

End ModuleProperty属性(Property)是类变量的公共描述。Property…End Property语句用以创建property。属性的Get/Set方法分别用于取得和设置属性值。下面的例子中,Data是TestClass的属性。

Imports System

Imports System.Console

Module Module1

Sub Main()

Dim cls As TestClass = New TestClass

WriteLine(cls.MyMethod)

WriteLine(cls.Data)

cls.Data = "New Data"

WriteLine(cls.Data)

End Sub

End Module

Class TestClass

Private strData As String = "Some Data"

Function MyMethod() As String

Return "Test Method!"

End Function

' Adding Data property to the class

Public Property Data() As String

Get

Return strData

End Get

Set(ByVal Value As String)

strData = Value

End Set

End Property

重载VB.NET通过overload关键字支持方法重载。使用这个关键字,你可以定义同名但不同参数的方法。

类成员访问域

除了原有的Private和Public,VB.NET引入了几个新关键字。全部访问域关键字列表如下:

关键字 作用域

Private 限于class内部

Public 可以从class外访问

Friend 限于class所属的应用程序内

Protected 只能被class和其派生类访问

Protected Friend 能被class、应用程序和派生类访问

继承继承是面向对象编程语言中最常用的技术。继承让你能够重用类代码和功能。

VB.NET支持继承,而VB6.0则不支持。继承的好处在于你能使用任何人编写的类,从这些类派生自己的类,然后在自己的类中调用父类功能。在下面的例子中,Class B派生自Class A,我们将从Class B中调用Class A的方法MethodA。

Imports System

Imports System.Console

Module Module1

Sub Main()

Dim bObj As B = New B

WriteLine(bObj.MethodA())

End Sub

End Module

' Class A defined

Public Class A

Function MethodA() As String

Return "Method A is called."

End Function

End Class

'Class B, inherited from Class A. All members (Public and Protected)

' can be access via B now.

Public Class B

Inherits A

Function MethodB() As String

Return "Method B is called."

End Function

End Class

可以从一个class中派生多个自定义class,也可以从多个class派生一个自定义class。

共享的成员类的共享成员被类的所有实体共享。共享成员可能是属性、方法或字段/值域。在你不想让用户全面控制自己的类时,共享成员相当有用。例如,你可以开发一个类库,让用户通过共享成员使用其中的部分功能。

可以通过class本身引用共享成员,而无需通过类的实体。例如:Module Module1

Sub Main()

WriteLine(A.MethodA())

End Sub

End Module

' Class A defined

Public Class A

Shared Function MethodA() As String

Return "Method A is called."

End Function

End Class

多线程VB语言的一大弱点就是缺乏编写自由线程(free-threaded)程序的能力。在.NET Framework中,所有语言共享CRL(Common Runtime Library,公共运行库),也就是说,你可以用VB.NET、C#或其它.NET语言编写同样的程序。

System.Threading namespace定义了线程类。我们只需要引入System.Threading namespace,即可使用线程类。

System.Threading.Thread类提供线程对象,可以使用Thread类创建或破坏线程。

创建线程使用Thread类的实体创建一个新线程,然后用Thread.Start方法开始执行线程。线程构造器接受一个参数,该参数指明你要在线程中执行的procedure。在下例中,我想在oThread1(Thread类的一个实体)的第二线程中执行SecondThread过程:

oThread1 = New Thread(AddressOf SecondThread)

SecondThread procedure looks like below:

Public Sub SecondThread()

Dim i As Integer

For i = 1 To 10

Console.WriteLine(i.ToString())

Next

End Sub

然后,调用Thread.Start()开始线程:

oThread1.Start()

下面的代码创建两个第二线程:

Imports System

Imports System.Threading

Module Module1

Public oThread1 As Thread

Public oThread2 As Thread

Sub Main()

oThread1 = New Thread(AddressOf SecondThread)

oThread2 = New Thread(AddressOf ThirdThread)

oThread1.Start()

oThread2.Start()

End Sub

Public Sub SecondThread()

Dim i As Integer

For i = 1 To 10

Console.WriteLine(i.ToString())

Next

End Sub

Public Sub ThirdThread()

Dim i As Integer

For i = 1 To 10

Console.WriteLine("A" + i.ToString())

Next

End Sub

End Module

破坏线程 调用Abort方法来破坏(中止)一个线程。在调用Abort之前,确保用IsAlive判断线程处于活动状态。

If oThread1.IsAlive Then

oThread1.Abort()

End If

暂停线程可以使用Sleep方法来暂停线程执行。Sleep方法接受一个以毫秒为单位的参数,指明线程应当暂停多长时间。

下面的例子让线程暂停1秒钟:

oThread2.Sleep(1000)你也可以使用Suspend和Resume方法来挂起和继续线程执行。

设定线程优先级Thread类的Priority属性用于设定线程优先级。该属性可以设置为Normal,AboveNormal,BelowNormal,Highest和Lowest。如:

oThread2.Priority = ThreadPriority.Highest线程与Apartment使用ApartmentState属性设置线程的apartment类型,该属性值可以为STA,MTA或是Unknown[][2]:

oThread.ApartmentState = ApartmentState.MTAMTS意味着可以使用多线程模式,而STA则只能是单线程执行。

Public Enum ApartmentState

{

STA = 0,

MTA = 1,

Unknown = 2,

}

1.8 结构化异常处理异常处理也被称之为错误处理。作为VB程序员,你一定对On Error Goto和On Error Resume Next这些VB6.0错误处理语句耳熟能详。这种类型的错误处理被称为非结构化异常处理(Unstructured Exception Handling)。而在VB.NET中,Microsoft推出了结构化异常处理机制。VB.NET支持类似C++的TryCatch..Finally控制。Try..Catch..Finally结构如下: Try

' 可能导致异常的代码

Catch

' 当异常发生时处理异常的代码

Finally

' 清理现场

End Try

Try语句块用以抛出异常。如果异常发生,在Catch语句块中处理。Finally语句块是可选的,在需要释放资源时特别有用。

1.9 VB6.0与VB.NET的不同之处除了上面谈到的语言进化,还有一些语法上的变化。所有这些语言和语法的变化在MSDN中均可查到,本文只作简单介绍。

数据类型(Data Type)的改变VB.NET中有些数据类型得到改进。下面是变化对照表。

数据类型 VB6.0 VB.NET

Integer 16 bit size 32 bit size

Long 32 bit size 64 bit size

Currency 用于存储大浮点数 被decimal替代,支持更高精度

Variant 可以存储任意类型数据 被Object类型替代,也可以存储任意类型数据,但结果更好

Date Date类型被存储为double 引入DateTime类型,用于存储不同格式的日期

在VB.NET中,Short数据类型是16 bit的。Short,Integer和Long都等同于CLR的System.Int16、System.Int32和System.Int64类型。 变量声明的变化在VB6.0中,变量声明有许多限制。其中之一就是不能同行声明多个变量。如果一定要在一行中声明多个变量,就一定得指明每个变量的类型,否则将被默认为Variant类型。

Dim a1, a2 As Integer Dim a3 As Integer, a4 As Integer 第一行中的a1是Variant类型,a2是Integer类型。第二行中两个变量都是Integer类型。VB.NET支持同行声明多个变量,举例如下:

Dim a1, a2, a3 As Integer 变量初始化是另一个问题。在VB6.0中不能同时声明和初始化变量,而VB.NET则支持这个特性。

Dim name As String = "Mahesh"System.Console.Write(name) 声明常量也可以照此办理:Const DT_COUNT As Integer = 23 New关键字。在VB.NET中,New关键字用于创建对象。由于数据类型是对象,所以New关键字用以创建一个数据类型对象。

Dim i As Integer = New Integer()i = 10System.Console.WriteLine(i.ToString()) 代码块级别支持。像C++一样,VB.NET支持代码块级别的作用域检查。在语句块中声明的变量只在块内有效。

For i = 1 To 10Dim p As LongSystem.Console.WriteLine(i.ToString())NextSystem.Console.WriteLine(p.ToString()) 这段代码在VB.NET中会得到一个编译错误,因为p在For..Next语句块之外不可访问。在VB6.0中这段代码可以通过。

改进了的类型安全

在VB6.0中,当你声明一个对外部过程的引用时,可以指定任意类型的参数为As Any。Any关键字禁止了类型检查,允许任意数据类型传入和返回。

VB.NET不支持Any关键字。你必须指定每个参数和返回值的数据类型。数组VB.NET对数组作了明显的改动。

数组范围。在VB.NET中,你需要格外留意数组范围问题。VB6.0默认数组下界为0,故数组中的元素数量等与数组上界值加一。下面的数组界限从A(0)到A(10),共有11个元素:

Dim A(10) As Single可以使用Option Base改变下界值为1。在VB.NET中,数组和C++一样,下界值为0,不支持Option Base。注意:MSDN文档指出数组只能包括与其尺寸相等的元素数量,例如:Dim A(10) As Integer 只能包括10个元素(从A(0)到A(9)),但在编译下面这段代码时我发现它运行良好,看起来数组中容纳了11个元素。

Dim A(10) As Integer A(0) = 12 A(2) = 24 A(10) = 23 System.Console.WriteLine(A(0).ToString()) System.Console.WriteLine(A(10).ToString())System.Console.WriteLine(UBound(A).ToString()) System.Console.WriteLine(LBound(A).ToString()) Lbound和Ubound分别返回 0与10。ReDim和Fixed Array。你可以在VB6.0中指定固定长度的数组。

Dim ArrWeekDays(0 To 6) As Integer

这里的ArrWeekDays数组是固定长度的,不能用ReDim语句改变长度。VB.NET不支持固定长度数组,所以ReDim总是有效。

可以用下面两种方式声明数组: Dim ArrWeekDays(6) As IntegerDim ArrWeekDays() As Integer = {1, 2, 3, 4, 5, 6} ReDim语句。在VB6.0中,ReDim用于初始化动态数组。在VB.NET中你不能把它当作声明用。ReDim只能用于改变数组长度,不过不能改变数组维度。

Variant对阵ObjectVB6.0中的Variant数据类型能存储任意类型变量,VB.NET中Object具备相同能力。

算术操作符VB.NET支持类似C++的快捷方式。下面的表格显示了常规操作与快捷操作的不同之处。快捷方式也可用于*、/、|、等操作符。

操作符 常规语法 快捷方式加法 A = A+5 A +=5 减法 A = A – 5 A -+ 5固定长度字符串

在VB6.0中,可以在声明字符串时指定其长度。VB.NET不支持固定长度字符串。

布尔操作符VB6.0中的And、Or或是Xor语句是按位操作符。而在VB.NET中,它们是布尔操作符。执行这些操作将返回true或false。VB.NET引入新操作符来完成按位操作。

操作符 描述 BitAnd 按位AndBitOr 按位OrBitXor 按位XorBitNot 按位Not结构与自定义类型在VB6.0中,你使用Type…End Type语句块创建结构或自定义类型。例如:

Type StdRec

StdId As Integer

StdName As String End Type

VB.NET引入新的语法:Structure。Type…End Type不再被支持。Structure…End Structure与C++用法相同。可以指定结构中每个元素的可访问域,如Public、Protected、Friend、Protected Friend、Private等。例如:

Structure StdRec

Public StdId As Integer Public StdName As String

Private StdInternal As String End StructureVB.NET中的Structures就像类一样,也可以拥有方法和属性。New和Nothing关键字VB6.0中,AS New和Nothing关键字用于声明一个对象并初始化它。 VB.NET不支持隐式创建对象。如前所言,甚至连数据类型都是对象。你可以采用以下两种方法创建数据类型或对象: Dim i As Integer Dim i As Integer = New Integer() // Do something if i = Nothing Then End If 不支持Set语句VB6.0使用Set语句指派对象。例如:Set myObj = new MyObjectSet a = b在VB.NET中,不需要使用Set指派对象。例如:myObj = new MyObj()a = b过程(procedure)语法的变化在VB.NET中过程语法有了很多变化。例如类似C++的过程调用方式、ByVal(传值)为默认类型、Optional关键字、return语句等等。类似C++的过程调用方式 VB6.0允许不用加圆括号调用过程(sub)。不过,用Call语句调用函数或sub时,一定要使用圆括号。例如:Dim I as IntegerCall EvaluateData(2, i) EvaluateData 2, i 在VB.NET中,所有的方法调用都需要圆括号,而Call语句则是可选的。 ByVal是默认参数类型在VB6.0中,在调用函数或sub时ByRef(传址)是默认类型。那意味着所有改变将反映到传入的变量。VB.NET改变了这种方式。现在,默认的参数类型是ByVal(传值)。 Optional关键字VB6.0使用Optional关键字可用来让用户决定传入一个默认值,之后在调用IsMissing函数判断参数是否有效。 而在VB.NET中,每个可选参数必须声明其默认值,无需调用IsMissing函数。例如:Sub MyMethod(Optional ByVal i As Integer = 3)

Return语句VB.NET的Return语句与C++相似。使用Return语句把控制权从过程返还给调用者。在VB6.0中,Return语句与GoSub语句一起使用。VB.NET不再支持GoSub语句。流程控制的改变下面是VB.NET对流程控制语句的修改:1. GoSub不再受到支持。2. Call、Function和Sub语句均可用于调用过程。3. On ... GoSub和On ... GoTo语句不再受支持。可以使用Select Case语句来替代。4. While ... Wend语句现在改为While…End While语句。不再支持Wend关键字。小结 Visual Basic .NET是.NET版本的Visual Basic,已经从根本发生了变化!通过本文你了解到VB6.0和VB.NET的区别是很大的,可以说根本就是两种不同的语言,因为它们的内核发生了变化,VB6.0是基于COM而vb.net是基于.net框架的,因为这个变化,所以在构造类时也发生了根本性的变化。

计算机的常用文件夹中出现一些*.dll的文件,不知道是什么东西?请路过的朋友给指导一下,先谢谢了。

CLR对组件代码的打包、部署和查找有自己的一套概念和技术。

这些概念和技术和COM、java和win32存在着本质上的区别。我们必须先弄清楚代码和元数据是如何打包的。

1.1 模块定义

CLR程序存在模块(module)中。一个CLR模块是一个字节流,通常作为一个文件存储在本地的文件系统中或者WEB服务器上。

CLR模块采用Windows NT的PE(Portable Exectuable)/COFF(Common Object File Format)可执行文件格式的扩展版。

当CLR编译器对C#、VB.NET等源程序编译后,产生MSIL(微软中间语言)和元数据。

元数据描述代码中的类型,包含每种类型成员的签名、代码引用的成员和运行库在执行时使用的其它数据。

MSIL和元数据包含在一个PE文件中,此文件基于并扩展过去用于可执行内容的已公布的Micorsoft PE和COFF。

CLR模块包含代码、元数据和资源。

模块代码:一般以公共中间语言的格式存放;

模块元数据:描述了模块中定义的类型,包含名字、继承关系、方法签名和依赖信息等。

模块的资源:静态的只读数据,例如,字符串、位图,以及其他没有被存储为可执行代码的部分。

CLR模块格式:

PE/COFF表头 PE头

COFF头

PE/COFF .text部分 IMAGE_COR20_HEADER

代码(CIL和/或本机机器码)

资源数据

字符串/BLOB池

元数据表

CLR模块格式输出选项:

C#/VB.NET C++ 直接可加载? 从Shell中可直接运行? 可访问控制台?

/t:exe /CLR 是 是 总是

/t:winexe /CLR /link /subsystem:windows 是 是 从不

/t:library /CLR /LD 是 否 依赖主机(Host-dependent)

/t:module /CLR:NOASSEMBLY /LD 否 否 依赖主机(Host-dependent)

选项/t:module产生“未加工的(raw)”模块,其文件扩展名默认为.netmodule。

这种格式的模块不能独立地部署,CLR也不能直接加载它们。

准确地说,开发人员必须在部署前,将这些“未加工的”模块和成型的组件(被称为程序集(Assembly))进行关联。

相比之下,用/t:library选项编译产生的模块,能够包含附加的元数据,允许开发人员将其作为独立代码进行部署。

选项/t:library编译产生的模块,其文件扩展名默认为.DLL。

“未加工的(raw)”模块没有程序集清单。“未加工的(raw)”模块也称作为能添加到其他程序集的模块。

1.2 程序集(Assembly)

为了部署CLR模块,开发人员首先必须将其归属于一个程序集(Assembly)中。程序集就是一个或多个模块的逻辑组合。

尽管程序集可能由多个模块组成,但是一个模块往往只属于一个程序集。假如出现两个程序集都引用同一个公共模块的情况,

CLR将这个公共模块视为两个不同的模块,即公共模块中的每个类型都有两个不同的拷贝。

在CLR中,程序集是部署的“原子”,被用来对CLR模块进行打包、加载、分发以及版本控制(物理的)。虽然程序集可能

包括多个模块以及辅助文件,但程序集本身被作为原子单元进行命名和版本化的。

程序集规定了组件中类型定义的作用域。CLR类型将它们的程序集名/类型名对作唯一标识。

C# VB.NET 意义

类型 Public Public 访问类型不受限制

Internal Friend 类型只在程序集内部可访问

成员 Public Public* 访问成员不受限制

Internal Friend 成员只在程序集内部可访问

Protected Protected 访问仅限于包含类或者包含类派生的子类型

Protected internal Protected friend 访问仅限于包含类以及包含类派生的子类型,或者当前程序集的其它类型。

Private Private 访问仅限于包含类型

*在VB.NET中,通过关键字DIM声明的方法默认为public,而字段默认为private。

程序集名字:

每个程序集的都采用四部分(four-part)名字,作为唯一标识符。这四部分名字由名称、文化、开发人员以及组件版本构成。

这些名字被存放于程序的清单中,以及引用它的所有程序集的程序集清单中。在加载时,CLR使用四部程序集名字找到正确的组件。

程序集的命名约定通常是基于命名空间前缀的。例如,.NET XML被部署在System.Xml程序集中,它包含的所有类型都使用System.Xml的

命名前缀。这仅仅是个约定,而不是规则。例如,类型System.Object存放在mscorlib的程序集中,而不是System的程序集中。

程序集名字的Name属性往往与程序集清单的底层文件名(不包含任何文件扩展明,尽管它们可能有用)相对应。当构建(Build)程序集时,

名字的这个部分是由编译器根据目标文件名自动选择的。

2 CLR类型

2.1 CLR类型

类型是CLR程序的生成快。开发人员在程序集的上下文中创建类型。当开发人员确定了把工程划分成一个或者多个程序集后,

他们的大部分时间就都花在考虑类型是如何工作的,以及类型直接是如何相互关联的。

CLR类型(CLR type)是命名的可重用抽象体。CLR类型的描述存放在CLR模块的元数据中,

该模块还包含使类型工作所需要的CIL或者本机代码。完全限定的CLR类型名包括三部分:程序集名字、可选的命名空间前缀和类型名称。

2.2 命名空间(namespace)

命名空间是一个逻辑的组织系统,开发人员在程序集开发上下文环境中使用命名空间来组织他们的类型系统。

这能帮助程序员在单个程序中使用两个或者多个同名的类型定义,只要它们分属不同的命名空间。这个命名空间前缀是一个字符串,

一般以开发人员的组织名(例如,Microsoft、MyCorp)开始;如果是.NET Framework的一部分,则以System开始。

3 小结

1)程序集用于组件的打包、部署、分发以及版本控制;命名空间前缀用于类型系统的逻辑划分。

2)程序集的名字由四部分组成,而其Name属性往往与程序集清单的底层文件名(不包含任何文件扩展明,尽管它们可能有用)相对应。

3)程序集的命名约定通常是基于命名空间前缀的,但这不是必须的。

4)如果要用到其它程序集中的类型,可以有两种方式:显式的和隐式的。通常我们都使用隐式的,这种方式不需要开发人员和程序集加载器进行显式的交互。只要在编译我们的程序集时,将需要的外部程序集使用/reference:file选项链接进来即可;如果使用显式的方式,开发人员可以使用System.Reflection.Assembly类的LoadFrom静态方法。

5)通常开发人员在自己的程序集上下文环境中时,主要打交道的是类型,以及类型的逻辑组织(namespace prefix)。

6)这里有两种主要的程序集种类,应用程序(.exe)和库(.dll)。

VB.NET的API调用

现在我用我所知道的为楼主介绍VB.NET的API调用,请楼主浏览一下,看看行不行。

Windows API就是Windows系统的API函数简称(Application Program Interface,即:应用程序接口函数),它是Windows操作系统提供给各种开发基于Windows平台应用软件的开发语言的一些公用的函数,这些函数一般都比较底层,所以当各种开发语言使用自带的函数或类库已无法解决问题时,调用Windows API函数往往是一种非常直接、有效的解决方法。但由于在程序中调用Windows API函数一般都很复杂,所以对于程序员来说,是否能够灵活的使用Windows API函数,往往也是其水平高低的一个重要标志。但自从微软推出.Net框架以后,各种开发基于.Net平台下的程序语言,如Visual Basic .Net、Visual C#等却很少使用Windows API函数,并且微软公司也不像以前那样,提倡在这些.Net开发语言中使用Windows API函数,其主要的原因如下:

1. .Net框架所附带的类库.Net FrameWork SDK是一个内容丰富、功能强大的软件开发包,各种Windows API函数所实现的各种功能几乎都可以在这个软件开发包中找到与之对应的部分。

2. 微软Visual Basic .Net、Visual C#等目的是编写跨平台的应用程序,如果在Visual Basic .Net、Visual C#等中使用Windows API函数,这也就注定了编写出的程序只能运行于Windows平台之下,而弱化了.NET的跨平台能力。这也就是为什么微软不提倡在.Net平台调用Windows API函数的原因。

虽然微软并不提倡在Visual Basic .Net、Visual C#中调用Windows API函数,但由于目前.Net 框架推出时间较短,.Net FrameWork SDK中提供的类库还并不足以完全替换Windows API函数的所有功能,所以在某些时候,.Net开发语言还是必须要调用Windows API函数。

一.平台调用、托管DLL、非托管DLL简介:

托管DLL就是能够在公共语言运行库(Common Language Runtime,简称CLR)中能够直接引用的,并且扩展名为“DLL”的文件。具体所指就是封装各种命名空间所在的DLL文件,如System.dll等。非托管DLL就是平常所的动态链接库等,其中就包括了封装所有Windows API函数的DLL文件。各种非托管DLL中的函数在公共语言运行库中不能直接被调用,而需要经过.Net框架提供的“平台调用”服务后才可以。

“平台调用”是.Net框架为Visual Basic .Net、Visual C#等.Net开发语言提供的一种服务,用以在托管代码中引入各种非托管DLL中封装的函数(其中包括Windows API函数)。“平台调用”依赖于元数据在运行时查找导出函数并封装其参数。图01公共语言运行库利用“平台服务”调用非托管DLL中的函数的流程图:

图01:“平台服务”的调用非托管函数的流程图

在托管代码中使用“平台调用”服务调用非托管DLL中封装的函数时,“平台服务”将依次执行以下操作:

1. 查找包含该函数所在的DLL文件。

2. 如果找到,则将该DLL文件 加载到内存中。

3. 查找函数在内存中的地址并将其参数推到堆栈上,并封送所需的数据。

4. 将控制权转移给非托管函数。 这样整个函数调用完成。

在Visual Basic .Net中使用“平台调用”服务,申明Windows API函数主要有二种具体的实现方法:

1. 使用DllImport特征类来申明Windows API函数。

2. 使用“Declare”语句来申明Windows API函数。

这二种方法虽有异曲同工之效,但在繁简上却有很大差异,第一种方法申明过程比较复杂,很容易在申明Windows API函数时出错,所以并不提倡。而第二种方法相对简单,并且又保存了以前Visual Basic中的很多语法,所以在平常时大都使用这种方法来申明Windows API函数。

二.VB.Net查看文件中图标的函数及申明Windows API的方法:

Visual Basic .Net要实现查看文件中的图标,目前只使用.Net FrameWork SDK是无法实现这种功能的,正如前面所说,主要是由于.Net FrameWork SDK推出的时间较短,其功能还不可能面面俱到。解决问题的关键是正确使用Windows API函数,其中所涉及到的Windows API函数主要有二个:其一是获得指定文件中的图标数目;其二是从指定文件的指定位置导出图标的Windows句柄。这二个函数都位于“Shell32.dll”文件中,并且函数的入口点都为“ExtractIcon”。下面是在Visual Basic .Net中分别使用DllImport特征类和“Declare”语句申明这二个Windows API函数的具体方法。

(1).使用DllImport特征类来申明Windows API函数:

下面是在Visual Basic .Net中使用DllImport特征类申明二个Windows API函数的具体示例:

'函数ExtractIcon,其功能是是从指定文件的指定位置导出图标的Windows句柄。

< System.Runtime.InteropServices.DllImport ( "Shell32.dll" , EntryPoint := "ExtractIcon" ) > _

Public Function _

ExtractIcon ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As UInt32 ) As System.IntPtr

End Function

'函数Icon_Num,其功能是获得指定文件中的图标数目

< System.Runtime.InteropServices.DllImport ( "Shell32.dll" , EntryPoint := "ExtractIcon" ) > _

Public Function _

Icon_Num ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As Integer ) As Integer

End Function

在使用DllImport特征类申明Windows API函数时,如果申明的函数名称和函数的入口点相同,则可以在申明Windows API函数时,省略定义函数入口点对应的代码,即EntryPoint对象字段对应的代码,这样声明ExtractIcon函数的代码也可以简化为如下所示:

< System.Runtime.InteropServices.DllImport ( "Shell32.dll" ) > _

Public Function _

ExtractIcon ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As UInt32 ) As System.IntPtr

End Function

(2).使用“Declare”语句来申明Windows API函数:

使用“Declare”语句的确比使用DllImport特征类要简单了许多,下面是在Visual Basic .Net中使用“Declare”语句来声明上述二个Windows API函数的具体方法:

Declare Auto Function ExtractIcon Lib "Shell32.dll" Alias "ExtractIcon" ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As UInt32 ) As System.IntPtr

'声明ExtractIcon函数

Declare Auto Function Icon_Num Lib "Shell32.dll" Alias "ExtractIcon" ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As Integer ) As Integer

'声明Icon_Num函数

在Visual Basic .Net中声明Windows API函数时,“Declare”语句中Alias关键字的作用相当于使用DllImport特征类中的EntryPoint对象字段。同样在使用“Declare”语句声明Windows API函数时,如果声明的函数和函数的入口点相同,也可以省略Alias关键字对应的代码,所以ExtractIcon函数也可以简化为如下:

Declare Auto Function ExtractIcon Lib "Shell32.dll" ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As UInt32 ) As System.IntPtr

下面就结合一个示例的编写过程来掌握的这二个Windows API函数的具体使用方法,这个示例的作用就是读取指定文件中的图标数目,并显示文件中的图标。

三.本文中程序的编写、调试和运行环境:

(1).视窗2000高级服务器版。

(2).Visual Studio .Net 2003企业结构设计版,.Net FrameWork SDK版本号4322。

四.Visual Basic .Net读取文件中的图标的实现步骤:

下面介绍的示例,其功能读取指定文件中包含的图标数目,并把这些图标全部显示出来。下面是这个示例的实现步骤:

1. 启动Visual Studio .Net。

2. 选择菜单【文件】|【新建】|【项目】后,弹出【新建项目】对话框。

3. 将【项目类型】设置为【Visual Basic项目】。

4. 将【模板】设置为【Windows应用程序】。

5. 在【名称】文本框中输入【Visual Basic .Net查看文件中的图标】。

6. 在【位置】的文本框中输入【E:\VS.NET项目】,然后单击【确定】按钮,这样在【E:\VS.NET项目】目录中就产生了名称为【Visual Basic .Net查看文件中的图标】文件夹,里面存放着【Visual Basic .Net查看文件中的图标】项目的所有文件。具体如图02所示:

图02:【Visual Basic .Net查看文件中的图标】项目的【新建项目】对话框

7. 选择菜单【项目】|【添加新项】,在弹出的对话框中的【模板】设置为【模块】,【名称】文本框设置为【Module1.vb】后。单击【打开】按钮,则在项目中增加了一个模板文件,名称为【Module1.vb】。

8. 把Visual Stuido .Net的当前窗口切换到Module1.vb的代码编辑窗口,并在其Module1的代码区中添加下列代码,下列代码是用二种方式声明二个Windows API函数:

< System.Runtime.InteropServices.DllImport ( "Shell32.dll" ) > _

Public Function _

ExtractIcon ( ByVal src As System.IntPtr , ByVal strFileName As String , ByVal uiIconIndex As UInt32 ) As System.IntPtr

End Function

'声明ExtractIcon函数

Declare Auto Function Icon_Num Lib "Shell32.dll" Alias "ExtractIcon" ( ByVal src As System.IntPtr , ByVal strFileName As String , ByVal uiIconIndex As Integer ) As Integer

9. 把Visual Studio .Net的当前窗口切换到Form1窗体的设计查看,并从【工具箱】中的【Windows窗体】选项卡中拖入下列组件到Form1窗体:

四个Label组件,其中二个用以显示提示信息,另外二个分别用以显示选择的文件名称和这个文件中包含的图标数目。

一个ListView组件,利用其显示大图标的属性用以显示选定文件中的图标。

一个OpenFileDialog组件,用以选择要查看图标的文件名称。

一个ImageList组件,它起的是桥梁的作用,首先把从文件中导出的图标存放到这里,然后再提供ListView组件显示出来。

一个Button组件。

10. 按照表01中数值来设定设定组件的主要属性:

组件类型 组件名称 属性 设置结果

Form Form1 Text VB.NET查看文件中的图标

Form1 MaximizeBox False

Form1 MinimizeBox False

Form1 FormBorderStyle FixedSingle

ListView ListView1 ImageList1 LargeImageList

ListView1 MultiSelect False

ListView1 Size Size ( 380 , 208 )

Button Button1 Text 选择文件

Button1 FlatStyle Flat

ImageList ImageList1 Size Size ( 32 , 32 )

ImageList1 TransparentColor Color.Transparent

Label Label1 Text 文件名称:

Label2 Text 图标数目:

Label3 Text ""

Label4 Text "0"

表01:【Visual Basic .Net查看文件中的图标】项目窗体中各组件的主要属性设定数值表

并按照图02中各组件的位置、大小和排列方式来调整窗体中各个组件:

图02:【Visual Basic .Net查看文件中的图标】项目的设计界面

11. 把Visual Studio .Net当前窗口切换到Form.vb的代码编辑窗口,并用下列代码替换Form1.vb中的Button1组件的Click事件的处理代码,下列代码是在Button1组件的Click事件中处理查看文件中图标的功能,具体如下:

Private Sub Button1_Click ( ByVal sender As System.Object , ByVal e As System.EventArgs ) Handles Button1.Click

If OpenFileDialog1.ShowDialog ( ) = DialogResult.OK Then

'清除组件中的所有项目

ListView1.Items.Clear ( )

ImageList1.Images.Clear ( )

Dim sfName As String = OpenFileDialog1.FileName

Label3.Text = sfName

Dim iIcon_Num As Integer = Icon_Num ( IntPtr.Zero , sfName , -1 )

'显示文件中的图标数目

Label4.Text = iIcon_Num.ToString ( )

Dim i As Integer

For i = 0 To iIcon_Num - 1 Step 1

'强制实现int到uint类型转换

Dim j As UInt32

j = System.Convert.ToUInt32 ( i )

Dim hIcon As System.IntPtr = ExtractIcon ( IntPtr.Zero , sfName , j )

'在imageList1组件中加入当然提取的图标

ImageList1.Images.Add ( Icon.FromHandle ( hIcon ).ToBitmap ( ) )

'在ListView组件中加入一个项目

ListView1.Items.Add ( "第" + ( i + 1 ).ToString ( ) + "个图标" )

'把加入项目的图象索引指向刚才加入图标在imagList1组件中的索引,从而显示图标

ListView1.Items ( i ).ImageIndex = i

Next i

End If

End Sub

12. 至此,在上述步骤都正确执行后,【Visual Basic .Net查看文件中的图标】项目的全部工作就完成了。单击快捷键F5就可以运行程序,此时单击【选择文件】按钮选择文件后,程序就能够读取这个文件中的图标及其数目,并显示出来了。具体如图03所示:

图03:【Visual Basic .Net查看文件中的图标】项目的运行界面

五.总结:

解决Visual Basic .Net查看文件中的图标的关键并非是使用.Net框架中提供的类库,而是使用Windows的API函数。虽然这与利用Visual Basic .Net开发跨平台程序的初衷相违背,但的确不失为一种解决问题的方法。有些时候通过Windows API函数能够快捷、方便的解决实际问题,而这往往是只使用.Net FrameWork SDK所望尘莫及的,但随着.Net FrameWork SDK内容的不断丰富,各种新的组成部分和新的功能不断加入,可以预见的是,在未来的.Net FrameWork SDK中必将拥有可以替换本文中介绍的二个Windows API函数的组成部分。


当前名称:vb.net从元数据的简单介绍
文章URL:http://jkwzsj.com/article/dososdj.html

其他资讯