ПрограммированиеVB.NET разработчик, архитектор

Опишите особенности и правильное использование структуры (Structure) в Visual Basic по сравнению с классами (Class). Какие ограничения существуют при их применении и чем они отличаются от классов в плане управления памятью и поведения?

Проходите собеседования с ИИ помощником Hintsage

Ответ

В Visual Basic структуры определяются с помощью ключевого слова Structure. Они:

  • Являются типами значения (value type): размещаются в стеке либо внутри других объектов;
  • Не поддерживают наследование от других пользовательских типов (но могут реализовывать интерфейсы);
  • Не могут иметь конструктор без параметров, кроме стандартного конструктора вне тела структуры;
  • Не могут быть объявлены как MustInherit (abstract) либо содержать финализаторы;
  • Являются хорошим выбором для маленьких, неизменяемых объектов, экономящих память на куче.

Пример

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 возникла путаница при копировании структур, содержащих ссылочные поля — изменяя массив внутри структуры, разработчик не ожидал, что изменится оригинал всюду, где был скопирован массив, несмотря на “value type”.


История

3. В бухгалтерском ПО смешивали структуры с классами для бизнес-сущностей: попытка реализовать наследование для структуры завершилась ошибкой компиляции, пришлось реорганизовать архитектуру системы, что оказалось трудозатратным из-за изначально неверного выбора между структурами и классами.