Carl 发表于 2009-12-15 17:37:00

【ZT】VB.NET 中Structure和Class的异同点

Post by "grapeman", 2008-07-09, 15:07
-----------------------------------------------------
http://hi.baidu.com/stevenlimin/blog/item/1f48ec1bce0a65d0ac6e753e.html
VB.NET 中Structure和Class的异同点
2008-05-27 19:18
相同处
[*]都是Contrainer类型,意味着都可以将其它类型作为成员[*]都可以有成员,所包括构造函数,方法,属性,域,常量,枚举,事件和事件Handler[*]成员可设成Public或Private[*]都可以实现接口[*]都可以有shared constructors, with or without parameters.[*]都可以有一个默认属性[*]都可以声明并且发起一个事件,都可以声明委托不同处 [*]Structure是值类型,classe是引用类型[*]Structure用栈来分配; classe用堆来分配[*]structure的成员默认情况下是公共的,而Class的成员变量和常量默认情况下是私有的而其它成员默认情况下是公共的.这与VB6是相兼容的。[*]structure必须至少有一个非共享的成员变量或事件成员,class可以完全是空的.[*]Structure的成员不能声明成Protected; class成员可以.[*]一个structure过程只能在它是一个Shared Sub时才能handle events而且只能通过AddHandler语句;而任何class过程都可以handle events,既可以用Handles关键字或 AddHandler语句。[*]Structure variable declarations cannot specify initializers, the New keyword, or initial sizes for arrays; class variable declarations can.[*]Structure继承自ValueType类,不能从其它任何类型继承; classes可以从任何不是ValueType的类继承[*]Structure不能继承而Class可以[*]Structure从来不析构terminated因此common language runtime (CLR)从来不调用它的Finalize方法,classe由垃圾回收器进行析构, 当没有任何对该类的引用时调用它的Finalize方法[*]structure 不需要一个构造函数,而Class需要[*]Structure只能有带参数的非共享的构造函数; classes 可以有带或不带参数的构造函数. 每个Structure都有一个默认的不带参数的构造函数以对其成员进行初始化,你可以重新定义该函数实例与变量
Structure是一个ValueType,也就是值类型,因此每一个Structure变量都绑定到一个Structure的实例。而类是引用类型,可以多个类变量指向同一份类实例 [*]Structure的变量声明时相当于调用了Structure的不带参数New,如Dim stru as Structure1相当于Dim stru as Structure1 = New Structure1()[*]当将一个Structure变量赋值给另一个Structure变量时,将这个变量的所有成员的值复制一份给新的Structure,而将一个类变量赋值给另一个时,只是将一个引用传给它,指向的是同一份类[*]可以将一个Nothing赋值给一个Structure变量,但这个Structure变量可以继续工作(只是其中的成员变成了初始值,也不能用 IsNothing 来判断该Structure是否是Nothing),但一个类变量如果是Nothing的话,将不能对该类的成员进行操作。[*]不同的类变量可以指向同一个对象,对一个类变量的成员进行改动,另一个类变量的成员也就改变了,但不同的Structure变量的内容[*]类的相等操作只是比较它们所指的对象是否为同一份,而Structure变量的相等操作是比较两个Structure中的各成员的值是否相等。




Reply by "winking",2008-07-11, 14:01
-----------------------------------------------------
我也凑个热闹!来自MSDN,:-)
结构和类
相同:

结构和类在以下方面相同:
1、两者都属于“容器”类型,这意味着它们包含其他以成员形式存在的类型。
2、两者都具有成员,成员可以包括构造函数、方法、属性、字段、常数、枚举、事件和事件处理程序。但是,不要将这些成员与结构的声明“元素”混淆。
3、两者的成员可以分别有不同的访问级别。例如,一个成员可以声明为 Public,而另一个可以声明为 Private。
4、都可实现接口。
5、都有共享的构造函数,有或没有参数。
6、两者都可以公开“默认属性”,前提是该属性至少带有一个参数。
7、两者都可以声明和引发事件,而且两者都可以声明委托。
不同:
结构和类在以下方面有所不同:
1、结构是“值类型”,而类是“引用类型”。结构类型的变量包含此结构的数据,而不是像类类型那样包含对数据的引用。
2、结构使用堆栈分配,类使用堆分配。
3、所有的结构元素都默认为 Public;类变量和常数默认为 Private,而其他的类成员默认为 Public。类成员的这一行为提供与 Visual Basic 6.0 默认值系统的兼容。
4、结构必须至少具有一个非共享变量或非共享的非自定义事件元素;而类可以完全是空的。
5、结构元素不可声明为 Protected;类成员可以。
6、只有 Shared (Visual Basic)Sub 结构过程才能处理事件,并且只能使用 AddHandler 语句;而任何类过程都可以处理事件,并且可以使用 Handles 关键字或 AddHandler 语句。
7、结构变量声明不能指定初始值设定项或数组初始大小,而类变量声明可以。
8、结构从 System.ValueType 类隐式继承,不能从任何其他类型继承;而类可以从 System.ValueType 以外的其他任何类继承。
9、结构是不可继承的;而类可以继承。
10、结构从不终止,所以公共语言运行库 (CLR) 从不对任何结构调用 Finalize 方法;而类可由垃圾回收器 (GC) 终止,当检测到没有剩余的活动引用时,垃圾回收器将对类调用 Finalize。
11、结构不需要构造函数;而类需要。
12、结构仅当没有参数时可以有非共享的构造函数;类无论有没有参数都可以。
每一个结构都有不带参数的隐式公共构造函数。这个构造函数将结构的所有数据元素都初始化为默认值。不能重定义此行为。
另外,在实例和变量上有一些注意的!
由于结构是值类型,每个结构变量都永久地绑定到一个单独的结构实例。而类是引用类型,对象变量可在不同的时间引用各种类实例。此区别在下列方面影响结构和类的使用:
1、初始化。结构变量使用结构的无参数构造函数隐式包含元素的初始化。因此,Dim s As struct1 等效于 Dim s As struct1 = New struct1()。
2、给变量赋值。当将一个结构变量赋给另一个,或将结构实例传递给过程参数,所有变量元素的当前值都复制到新结构中。当将一个对象变量赋给另一个,或传递一个对象变量到过程,仅有引用指针被复制。
3、给 Nothing 赋值。您可以将值 Nothing (Visual Basic) 赋给结构变量,但实例继续保持与变量的关联。您仍可以调用变量的方法和访问它的数据元素,但赋值重新初始化了变量元素(所以s = Nothing等效于s = New struct1())。
    相比之下,如果将对象变量设为 Nothing,将其与任何类实例断开关联,在给它赋予另一个实例前,不能通过变量访问其他成员。
4、多个实例。一个对象变量可以有在不同时间赋给它的不同的类实例,多个对象变量可以同时引用同一个类实例。当通过指向同一实例的另一个变量访问时,更改的类成员的值会影响这些成员。
    但是,结构元素独立存在于其自身实例中。更改其值不会在其他任何结构变量中反映出来,即使是在同一 Structure声明的其他实例中。
5、相等。两个结构的相等测试必须以逐个元素地进行测试的方式执行。可使用 Equals 方法比较两个对象变量。Equals 指示两个变量是否指向同一个实例。
类与模块
相同:
类和模块均是封装在它们中定义的项的引用类型,但它们从其他过程访问这些项的方式有所不同。
当 Shared 修饰符应用于类成员时,它是与类本身相关联,而不是类的特定实例关联。使用类名可直接访问类成员,与模块成员的访问方式相同。

不同:
类和模块之间的主要差异在于:类可以实例化为对象,而标准模块则不能。由于标准模块的数据只有一个副本,因此当程序的一部分更改标准模块中的公共变量时,如果程序的其他任何部分随后读取该变量,都会获取同样的值。与之相反,每个实例化对象的对象数据则单独存在。另一个不同在于:不像标准模块,类可以实现接口。
类和模块对它们的成员使用不同的范围。在类中定义的成员其作用范围在类的特定实例内,并且只存在于对象的生存期内。要从类的外部访问类成员,必须使用“对象.成员”格式的全限定名称。
另一方面,在模块内声明的成员默认情况下是公共可访问成员,任何可访问该模块的代码都可以访问它。这意味着标准模块中的变量是有效的全局变量,因为它们在项目中的任何地方均可见,且存在于程序的整个生存期。
MSDN链接:
结构和类:http://msdn.microsoft.com/zh-cn/library/2hkbth2a(VS.80).aspx
类与模块:http://msdn.microsoft.com/zh-cn/library/7825002w(VS.80).aspx

Reply by "Carl ",2008-07-11, 14:24
-----------------------------------------------------
继续完善~
来自MSDN类库设计指南:
在类和结构之间选择
类是引用类型,而结构是值类型。引用类型在堆中分配,内存管理由垃圾回收器处理。值类型在堆栈上或以内联方式分配,且在超出范围时释放。通常,值类型的分配和释放开销更小。然而,如果在要求大量的装箱和取消装箱操作的情况下使用,则值类型的表现就不如引用类型。有关更多信息,请参见装箱和取消装箱(C# 编程指南)。
有关值类型和引用类型的更多信息,请参见通用类型系统概述。
不要定义结构,除非该类型具备以下所有特征:
[*]它在逻辑上表示单个值,与基元类型(整型、双精度型等)类似。[*]它的实例大小小于 16 字节。[*]它是不可变的。[*]它将不必频繁被装箱。如果这些条件中的一个或多个没有满足,则创建引用类型而不是结构。不遵守此准则会对性能产生负面影响。
结构设计
结构是值类型。结构是在堆栈上或以内联方式分配的,当结构超出范围时将被释放。通常情况下,值类型的内存空间分配和释放的开销较小;但在需要大量装箱和取消装箱操作的方案中,值类型的执行性能较引用类型要差。有关更多信息,请参见装箱和取消装箱(C# 编程指南)。
有关值类型和引用类型的更多信息,请参见通用类型系统概述。
[*]不要为结构提供默认的构造函数。如果某一结构定义了默认构造函数,则在创建该结构的数组时,公共语言运行库会自动对每个数组元素执行该默认构造函数。
有些编译器(如 C# 编译器)不允许结构拥有默认构造函数。
[*]对值类型实现 System.IEquatable`1。在确定两个值类型是否相等时,IEquatable<(Of <(T>)>) 要优于 Equals。通过使用接口,调用方可避免装箱和托管反射的不良性能影响。
[*]确保所有实例数据均设置为零、false 或 null(根据需要)的状态是无效的。如果遵循这一准则,新构造的值类型实例不会处于不可用的状态。例如,下面的结构的设计是错误的。参数化构造函数有意确保存在有效的状态,但在创建结构数组时不执行该构造函数。这意味着实例字段 label 初始化为 null(在 Visual Basic 中为 Nothing),这对于此结构的 ToString 实现是无效的。
[*]不要显式扩展 System.ValueType。有些编译器不允许扩展 ValueType。


页: [1]
查看完整版本: 【ZT】VB.NET 中Structure和Class的异同点