Структуры

Некоторые полагают, что структуры VB .NET аналогичны пользовательским типам прежних версий VB или многих других языков программирования. Конечно, структуры VB .NET могут использоваться как пользовательские типы, но этим область их возможного применения не исчерпана. Структура может обладать всеми признаками традиционного класса, включая конструкторы и члены с атрибутами Private/Friend/Public. Единственное отличие структур от обычных объектов заключается в том, что структуры обладают структурной семантикой. Вспомните, какой смысл вкладывается в этот термин:

  • передача по значению не изменяет состояния исходной переменной;
  • структуры создаются без использования оператора New, поэтому для них всегда определено значение по умолчанию, образованное значениями по умолчанию всех полей экземпляра;
  • в структуре определен метод Equals, который возвращает True, если две структуры содержат одинаковые внутренние данные (метод Equals используется в форме А.Еquals(В)).
  • В текущей версии VB .NET равенство двух экземпляров структурного типа не может быть проверено при помощи знака равенства (=). Вместо этого следует использовать метод Equals. По умолчанию метод Equals выполняет так называемое поверхностное (shallow) сравнение — смысл этого термина рассматривается в разделе «Клонирование объектов» главы 5. Если вы хотите, чтобы ваша версия Equals отличалась каким-то особым поведением, метод можно переопределить в определении структуры.

    Некоторые программисты используют структуры чаще, чем следует, полагая, что структура как1 облегченный объект работает эффективнее, чем объекты обычных классов. К сожалению, этот подход не лишен недостатков: два объекта, обладающие одинаковым состоянием, далеко не всегда должны считаться равными, тогда как при использовании структур это неизбежно. Кроме того, пользователи вашего кода обычно ожидают, что структуры (и структурные типы вообще) по своему поведению близки к встроенным структурным типам вроде Integer и Double.

    Все стандартные числовые типы (Integer, Long, и т.д.) реализованы B.NETFramewdrke виде структур.

     

    Определение структур в программе

    Определение структуры начинается с модификатора уровня доступа и ключевого слова Structure:

    Public Structure NameOfStructure

    ' Код структуры End Structure

    Для каждого члена структуры должен быть указан модификатор доступа (например, Public или Private). Поля, объявленные с ключевым словом Dim вне процедур и функций, считаются открытыми. Ниже приведен простейший вариант структуры для работы с комплексными числами:

    Public Structure ComplexNumber

    Private m_real As Double

    Private m_complex As Double

    Public Property real () As Double Get

    Return m_real

    End Get Set(ByVal Value As Double)

    m_real = Value

    End Set

    End Property

    Public Property complex()As Double Get

    Return m_complex End Get Set(ByVal Value As Double)

    m_complex = Value

    End Set

    End Property

    Public Sub New(ByVal x As Double. ByVal у As Double)

    real = x complex = у

    End Sub

    Public Function Add(ByVal zl As ComplexNumber) As ComplexNumber

    Dim z As ComplexNumber

    z.real = Me.real + zl.real

    Z.complex = Me.complex + zl.complex

    Return z End Function

    ' И т.д. End Structure

    Обратите внимание на возвращение структуры функцией Add. Кстати, поля структур не могут инициализироваться при объявлении:

    Private m_real As Double = 0 ' Ошибка

    Между структурами и ссылочными объектами существует еще одно принципиальное различие: использование открытых полей вместо свойств Get-Set в структурах широко распространено и не считается проявлением плохого стиля программирования, как для объектов. Это связано с тем, что поля экземпляров обычно относятся к базовым типам. Например, переопределение приведенной выше структуры ComplexNumber с открытыми полями Real и Imaginary не вызовет особых проблем.

    Структуры создаются вызовом New или при присваивании значений их полям. Обращения к полям структур осуществляются так же, как и обращения к свойствам объектов. Ниже приведен пример использования структуры Compl exNumber:

    Sub Main()

    Dim Z1 As New ComplexNumber(2.3. 2.4)

    Dim Z2.Z3 As ComplexNumber

    Z2.real = 1.3

    Z2.complex =1.4

    Z3 = Zl.Add(Z2)

    Console. WriteLine(Z3. real)

    Console.ReadLine()

    End Sub

    Текущая версия VB .NET не позволяет переопределять смысл операторов (то есть про-изводить перегрузку операторов), поэтому нам пришлось определить метод Add вместо того, чтобы задать новое определение для оператора «+». Возможность перегрузки операторов должна появиться в будущих версиях VB .NET. Если вы хотите, чтобы в сегодняшней версии вашего пакета для работы с комплексными числами сложение выполнялось знаком «+», придется использовать С#.

    Структуры могут содержать любые объекты VB .NET, в том числе другие структуры, перечисляемые типы, массивы и т. д. Таким образом, на VB .NET можно написать пакет для работы с матрицами, в котором основная структура данных будет определяться следующим образом:

    Public Structure Matrix

    Private TheOata(,) As Double

    ' И т.д. End Structure

     

    Пространства имен для создаваемых классов

    Классы, перечисляемые типы, структуры или модули включаются в пространства имен. Конечно, создать экземпляр модуля невозможно — только экземпляры классов, определяемых в модуле. В диалоговом окне Project Properties, показанном на рис. 4.9, присутствуют текстовые поля для имени сборки и корневого пространства имен,

    На рис. 4.9 указано корневое пространство имен Apress. При объявлении пространства имен в программе можно использовать иерархию произвольной глубины, отражающую логическую структуру нашей программы. Рассмотрим пример определения класса:

    Namespace Cornell.Morrison.VB.NET.CH4

    Module Module1

    Sub Main()

    Console.filriteLine("test code goes here")

    End Sub

    Public Class"EmployeeExamplel

    ' Код класса End Class

    End Module

    End Namespace

    Рис. 4.9. Пространство имен и имя сборки в окне свойств проекта

    В этом случае полное имя класса выглядит так:

    Apress.Cornell.Morrison.VB.NET.CH4.EmployeeExamplel

    Пространства имен .NET в отличие от пакетов Java не привязаны к определенной структуре каталогов. Два класса могут принадлежать одному пространству имен даже в том случае, если они определяются в разных файлах, находящихся в разных каталогах.

     

    Окно классов

    Теперь, когда вы знаете, как определять собственные классы, вам будет проще работать с окном классов, в котором члены классов вашего решения отображаются в виде удобного иерархического дерева. Окно классов помогает ориентироваться в коде вашего решения: при двойном щелчке в одной из строк окна классов в окне программы автоматически открывается код соответствующего члена. Окно классов открывается командой View > Class View или комбинацией клавиш Ctrl+Shift+C. На рис. 4.10 показано, как выглядит окно классов для одной из версий нашего класса Employee.

    Рис. 4.10. Окно классов для класса Employee

    В левом верхнем углу окна расположена пара кнопок. Кнопка New Folder создает новую папку, но чаще используется кнопка Class View Sort By Type. Она открывает список, в котором выбирается режим представления информации в окне.

  • Sort Alphabetically. Классы и члены упорядочиваются по алфавиту (a-z).
  • Sort By Type. Классы и члены упорядочиваются по типу. Например, в этом режиме удобно сгруппировать все свойства (базовых классов, интерфейсов, методов и т. д.).
  • Sort By Access. Классы и члены упорядочиваются по уровню доступа.
  • Group By Type. Классы и члены группируются в разных узлах в зависимости от типа. Например, все свойства объединяются в узле Properties, а все поля — в узле Fields.
  •