结构和类 (Visual Basic)

Visual Basic 将结构和类的语法统一,结果两个实体都支持大多数相同的功能。 但是,结构和类之间也存在重要的差异。

类具有引用类型的优势, 传递引用比传递包含其所有数据的结构变量更有效。 另一方面,结构不需要在全局堆上分配内存。

由于无法从结构继承,因此结构应仅用于不需要扩展的对象。 如果要创建的对象具有较小的实例大小,并考虑类与结构的性能特征,请使用结构。

相似 之 处

结构和类在以下方面类似:

  • 两者都是 容器 类型,这意味着它们包含作为成员的其他类型的类型。

  • 两者都有成员,其中包括构造函数、方法、属性、字段、常量、枚举、事件和事件处理程序。

  • 两者的成员可以具有个性化访问级别。 例如,可以声明Public作为一个成员,Private作为另一个成员。

  • 两者都可以实现接口。

  • 两者都可以具有共享构造函数,也可以不带参数。

  • 两者都可以公开 默认属性,前提是该属性至少需要一个参数。

  • 两者都可以声明和引发事件,并且两者都可以声明委托。

差异

结构和类在以下具体方面有所不同:

  • 结构是 值类型;类是 引用类型。 结构类型的变量包含结构的数据,而不是像类类型那样包含对数据的引用。

  • 结构使用堆栈分配;类使用堆分配。

  • 默认情况下,所有结构元素都是 Public ;类变量和常量默认为 Private ,而其他类成员则默认为 Public 类成员。 类成员的此行为提供与 Visual Basic 6.0 默认值系统的兼容性。

  • 结构必须至少有一个非共享变量或非共享的非custom 事件元素;类可以完全为空。

  • 结构元素不能声明为 Protected;类成员可以。

  • 结构过程只有当它是一个 共享Sub 过程时,并且仅通过 AddHandler 语句 才能处理事件。任何类过程都可以使用 Handles 关键字或 AddHandler 语句来处理事件。 有关详细信息,请参阅 事件

  • 结构变量声明不能指定数组的初始值设定项或初始大小;类变量声明可以。

  • 结构体隐式从 System.ValueType 类继承,不能从其他任何类型继承;类可以继承自除了 System.ValueType 以外的任何类。

  • 结构不可继承;类可以继承。

  • 结构永远不会被终止,因此公共语言运行时(CLR)永远不会在任何结构上调用 Finalize 方法。类由垃圾回收器(GC)终止,当垃圾回收器检测到该类不存在活动引用时,它会调用 Finalize 方法。

  • 结构不需要构造函数;但类需要。

  • 当结构体需要参数时,它们才能有非共享的构造函数,而类则无论带有或不带参数都可以有。

每个结构都有一个没有参数的隐式公共构造函数。 此构造函数将所有结构的数据元素初始化为其默认值。 无法重新定义此行为。

实例和变量

由于结构是值类型,因此每个结构变量将永久绑定到单个结构实例。 但类是引用类型,对象变量可以在不同的时间引用各种类实例。 这种区别会影响你在以下方面使用结构和类的方式:

  • 初始化。 结构变量隐式包括通过结构的无参数构造函数来初始化元素。 因此, Dim s As struct1 等效于 Dim s As struct1 = New struct1().

  • 分配变量。 将一个结构变量分配给另一个结构变量或将结构实例传递给过程参数时,所有变量元素的当前值将复制到新结构。 将一个对象变量分配给另一个对象变量或将对象变量传递给过程时,仅复制引用指针。

  • 不分配任何内容。 可以将 值 Nothing 分配给结构变量,但该实例将继续与该变量关联。 你仍然可以调用其方法并访问其数据元素,尽管变量元素由赋值重新初始化。

    相反,如果将对象变量 Nothing设置为,则将其与任何类实例取消关联,并且只有在向该变量分配另一个实例之前,才能通过该变量访问任何成员。

  • 多个实例。 对象变量可以在不同时间分配不同的类实例,多个对象变量可以同时引用同一个类实例。 通过指向同一实例的另一个变量访问时,对类成员的值所做的更改会影响这些成员。

    但是,结构元素在它们自己的实例中是隔离的。 更改其值不会反映在任何其他结构变量中,即使在相同 Structure 声明的其他实例中也是如此。

  • 平等。 必须使用逐一元素测试来执行两个结构的相等测试。 可以使用该方法 Equals 比较两个对象变量。 Equals 指示两个变量是否指向同一实例。

另请参阅