Иллюстрированный самоучитель по VB.NET

       

Структурные типы


Традиционно в объектно-ориентированных языках возникало немало проблем с простейшими типами данных — такими, как обычные целые числа. Дело в том, что в объектно-ориентированном языке все данные должны быть объектами. С другой стороны, создание объекта сопряжено с определенными затратами на выполнение служебных операций (таких, как выделение блока памяти для объекта). Обработка сообщения «сложить» также уступает по скорости простой математической операции сложения и т. д. Стоит добавить, что в языках с автоматической сборкой мусора некоторое время расходуется на уничтожение неиспользуемых объектов.

Ранние объектно-ориентированные языки пошли по самому прямолинейному пути. Скажем, в Smalltalk все данные интерпретировались как объекты. В результате такие языки работали медленнее, чем языки с разделением примитивных типов и объектов. С другой стороны, подобное разделение приводило к усложнению программ, поскольку программный код, работавший с числами, приходилось отделять от кода, работавшего с объектами. Чтобы интерпретировать число в объектном контексте, его приходилось «заворачивать» в объект. Например, в Java сохранение числа в эквиваленте динамического массива выглядело примерно так:

anArrayList.Add(Integer(5));

Число 5 «заворачивалось» в объект Integer. Такие программы плохо читались и медленно работали.

В .NET Framework были объединены лучшие стороны обоих решений. В общем случае числа интерпретируются как примитивные типы, но при "необходимости они автоматически интерпретируются как объекты. Таким образом, для обычного числового литерала можно вызвать метод или занести его в хэш-таблицу без дополнительных усилий. Это называется автоматической упаковкой (boxing); обратный процесс называется распаковкой (unboxing).

Для нас, программистов, из этого вытекает важное следствие: хотя в VB .NET все данные являются объектами, не каждая переменная в программе содержит манипулятор блока памяти и создается оператором New.
Разумеется, ничто не дается даром: программисту приходится помнить о различиях между структурными и ссылочными типами. Первое, наиболее очевидное различие заключается в том, что новые экземпляры структурных типов создаются без ключевого слова New. Вам не придется (да и не удастся) использовать конструкции вида Dim a As New Integer(5).

Более серьезное различие связано с передачей переменных процедурам по значению. Как было сказано выше, при передаче изменяемого объекта по значению процедура может изменить состояние объекта. Переданные по значению структурные типы ведут себя вполне традиционно — все изменения теряются при выходе из вызванной процедуры или функции (иногда это называется структурной семантикой в отличие от ссылочной семантики).

Все числовые типы VB .NET являются структурными типами; к этой же категории относится и такой тип, как дата. Как будет показано ниже, VB .NET позволяет определить пользовательские структурные типы, если по соображениям быстродействия вы хотите свести к минимуму затраты на работу с объектами или же предпочитаете работать с объектами, обладающими структурной семантикой.

Чтобы узнать, обладает ли некий тип структурной семантикой, передайте переменную этого типа следующей функции.

Function IsValueType(ByVal foo As Object)As Boolean

If TypeOf (foo)Is System.ValueType Then

Return True Else

Return False

End If

End Function

Для объектов структурного типа оператор Equal s всегда возвращает True, если структурные объекты содержат одинаковые данные. Синтаксис вызова выглядит так:

a..Fquals(b)

Учтите, что для ссылочных типов этот принцип в общем случае не выполняется. Например, два массива могут содержать одинаковые элементы, но равными при этом они не считаются.

В VB .NET структурные типы делятся на две категории: структуры и перечисляемые типы. Мы начнем с перечисляемых типов, а затем перейдем к структурам, которые представляют собой «облегченные» варианты объектов.




Содержание раздела