编程VB.NET 开发人员, 架构师

描述 Visual Basic 中结构(Structure)与类(Class)的不同特点和正确使用方法。在它们的应用中存在哪些限制,以及在内存管理和行为方面它们与类有什么不同?

用 Hintsage AI 助手通过面试

回答

在 Visual Basic 中,结构通过关键字 Structure 定义。它们:

  • 是值类型(value type):位于堆栈中或其他对象内部;
  • 不支持从其他用户定义类型的继承(但可以实现接口);
  • 除了结构体外部的标准构造函数外,不能有无参数构造函数;
  • 不能声明为 MustInherit(抽象),也不能包含终结器;
  • 对于小的、不可变的对象来说,结构是节省堆内存的良好选择。

示例

Public Structure Point Public X As Integer Public Y As Integer Public Sub New(x As Integer, y As Integer) Me.X = x Me.Y = y End Sub End Structure Dim p1 As New Point(1, 2) Dim p2 = p1 ' 复制值,不是引用! p2.X = 5 ' p1.X = 1, p2.X = 5

限制

  • 结构之间不能继承,只能从 System.ValueType 继承。
  • 只允许无参数的自动构造函数。
  • 只允许实现接口。
  • 如果结构包含引用成员,由于可能的复制和变更细节,应该谨慎使用。

陷阱问题

问:在通过 ByVal 和 ByRef 传递结构时,行为如何?与传递类有什么不同?

答:使用 ByVal 传递结构时,会创建整个结构的副本,函数中的更改不会影响原始值。使用 ByRef 时会更改原始变量。与类不同,即使是 ByVal 传递时也传递引用,结构在 ByVal 时会完全复制,这影响性能和行为。

Sub MutateByVal(p As Point) p.X = 100 End Sub Sub MutateByRef(ByRef p As Point) p.X = 100 End Sub Dim s As New Point(3, 4) MutateByVal(s) ' s.X 仍然是 3 MutateByRef(s) ' s.X 现在是 100

历史

1. 在一个大型图书馆项目中,结构用于通过接口 ByVal 传递大量数据数组。这导致由于大量复制大结构而降低了性能。通过用不可变类替换结构来解决了这个问题。


历史

2. 在 GIS 开发项目中,复制包含引用字段的结构时发生了混淆——开发者在修改结构内部的数组时没有预料到修改了所有地方的原始数组,尽管是“值类型”。


历史

3. 在会计软件中,结构与类混合用于商业实体:尝试对结构实现继承导致编译错误,必须重新组织系统架构,这由于最初在结构和类之间的不当选择而产生了额外的工作量。