Объявление переменных

В VB .NET, как и в VB6, переменные объявляются в процедурах и функциях при помощи ключевых слов Dim и As, а присваивание выполняется знаком =:

Dim foo As String

foo = "bar"

Если вы не изменяли стандартную настройку VB .NET, переменные должны объявляться перед использованием (режим Option Explicit, впервые представленный в VB4, теперь используется по умолчанию). В VB .NET поддерживается инициализация переменных при объявлении. Пример:

Dim salesTax As Decimal = 0.0825D

Команда объявляет переменную с именем salesTax и присваивает ей начальное значение 0.0825 типа Decimal. При инициализации могут использоваться любые синтаксически правильные выражения VB .NET. Следующая команда присваивает переменной startAngle встроенное значение математической константы п, используя для этого константу класса System. Math: Dim startAngle As Decimal - Math.PI

Если переменная не была инициализирована при объявлении, ей присваивается стандартное значение, соответствующее ее типу, — например, числовым переменным присваивается 0. При таком удобном синтаксисе, как в VB .NET, всегда лучше инициализировать переменную при объявлении, чем полагаться на значение по умолчанию. В следующем фрагменте используется оператор &, применявшийся в VB6 для конкатенации строк:

Sub Main()

Dim salesTax As Decimal = 0.0825D

Dim state As String = "California"

Console.WriteLine("The sales tax in " & state & " is " & salesTax)

Console. ReadLine()

End Sub

Программа выводит следующий результат:

The sales tax in California is 0.0825

В отличие от предыдущих версий VB, объявление нескольких переменных в одной строке программы работает именно так, как подсказывает здравый смысл. Иначе говоря, следующая команда объявляет три переменные: i, j и k, относящиеся к типу Integer:

Dim i, j, k As Integer

При одновременном объявлении нескольких переменных инициализация выполняться не может, поэтому следующая строка недопустима:

Dim i, j, k As Integer = 1

Как и в прежних версиях VB, вместо указания типа с ключевым словом As может использоваться суффикс типа. Например:

Dim i%, myname$

Приведенная команда объявляет переменную i типа Integer (аналог Long в старом VB) и переменную myName типа String. Программистам VB .NET поступать подобным образом не рекомендуется.

Все программисты хорошо помнят, какие жаркие дискуссии проходили по поводу соглашений об именах переменных. Существует сложная система префиксов (так называемая венгерская запись), позволяющая с первого взгляда определить тип переменных. Согласно общим рекомендациям программирования для .NET Framework применение венгерской записи нежелательно. Мы будем следовать этим рекомендациям, и в книге префиксы встречаются очень редко.

Команды семейства DefType (например, Deflnt) в VB .NET не поддерживаются.

 

Преобразования разнотипных значений

По мнению многих программистов, прежние версии VB6 слишком либерально относились к преобразованию типов. В результате возникало явление «злостного искажения типов» — скажем, VB6 позволял умножить строковое представление числа на Integer.

В VB .NET предусмотрен режим жесткой проверки типов Option Strict. Чтобы активизировать его, включите следующую команду в начало программы (также можно воспользоваться флажком Strict Type Checking на вкладке Build диалогового окна Project Properties):

Option Strict On

При активизации этого режима (а это следует делать всегда!) VB .NET требует, чтобы любые преобразования типов, которые могут привести к потере данных, выполнялись явно. Например, при преобразовании Single к типу Integer может произойти потеря точности, поскольку тип Integer не позволяет представить весь интервал допустимых значений типа Single. С другой стороны, если потеря данных исключена (скажем, при преобразовании Integer в тип Long или Decimal), VB .NET выполняет преобразование автоматически. В документации VB .NET преобразования без потери данных называются расширяющими преобразованиями (widening conversions). В табл. 3.3 переделены допустимые расширяющие преобразования для базовых типов данных.

Таблица 3.3. Допустимые расширяющие преобразования для базовых типов VB .NET

Тип
Допустимое расширение
Byte Byte, Short, Integer, Long, Decimal Single, Double
Short Short, Integer, Long, Decimal, Single, Double
Integer Integer, Long, DecimaL Single, Double
Long Long, DecimaL Single, Double
Single Single, Double
Date Date, String

Более того, при активном режиме жесткой проверки типов вы не сможете использовать конструкции вида:

Dim foo As Boolean

foo = 3

В этом фрагменте логической переменной foo значение True присваивается в виде ненулевого числа (в VB6 это было вполне распространенным явлением). Подобные преобразования должны выполняться явно:

Dim foo As Boolean

foo =СВооl(З)

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

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

Option Strict Off

Впрочем, поступать подобным образом не рекомендуется.

Если содержимое переменной одного типа может быть преобразовано к другому типу, можно воспользоваться функцией явного преобразования, как в только что приведенном примере с СВооl. Функции явного преобразования типов перечислены в табл. 3.4.

Таблица 3.4. Функции явного преобразования типов

Функция
Описание
CBool Преобразует выражение к типу Boolean
CByte Преобразует выражение к типу Byte
CInt Преобразует выражение к типу Integer с округлением
CIng Преобразует выражение к типу Long с округлением
CSng Преобразует выражение к типу Single
CDate Преобразует выражение к типу Date
СDbl Преобразует выражение к типу Double
CDec Преобразует выражение к типу Decimal
CStr Преобразует выражение к типу String
CChar Преобразует первый символ строки к типу Char

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

На первый взгляд кажется, что тип Char можно интерпретировать как короткое целое без знака (то есть целое в интервале от 0 до 65 535), но делать этого не следует. Начиная с бета-версии 2 было запрещено преобразование Char в число функциями семейства CInt; вместо этого используется встроенная функция Asc.

Тип object и исчезновение типа Variant

Вероятно, вы заметили, что при описании типов нигде не упоминается тип Variant. BVB .NET этот тип не поддерживается — и это очень хорошо! В VB6 переменные Variant допускали хранение данных произвольного типа. Программисты часто злоупотребляли этой возможностью, что приводило к возникновению нетривиальных ошибок в программах. В VB .NET все типы данных (даже числовые, как Integer) являются частными случаями типа Object. Может показаться, что тип Object стал аналогом Variant в VB .NET, но это не так. Как будет показано в главах 4 и 5, тип Object занимает в программировании .NET значительно более важное место и обладает множеством интересных возможностей. Мы вернемся к типу Object в главах 4 и 5.

Ниже приведен хрестоматийный пример — преобразование температуры по Цельсию в температуру по шкале Фаренгейта. Мы руководствуемся следующими предположениями:

  1. Пользователь завершает ввод текста нажатием клавиши Enter.
  2. Все введенные символы воспринимаются методом ReadLine().
  3. Пользователь ввел число, поэтому введенный текст преобразуется к числовому типу функцией CDec (конечно, на практике введенные данные следовало бы предварительно проанализировать):

' Преобразование температуры по Цельсию в температуру по Фаренгейту

Option Strict On Module

Modulel Sub Main()

Dim cdeg As Decimal

Console. Writer Enter the degrees in centigrade...")

cdeg = CDec(Console.ReadLine())

Dim fdeg As Decimal

fdeg = (((9@ / 5) * cdeg) + 32)

Console.WriteLine(cdeg & " is " & fdeg & " degrees Fahrenheit.")

Console. ReadLine()

End Sub

End Module

Обратите внимание на суффикс @ — он гарантирует, что при вычислениях будет использоваться тип Decimal. Если убрать этот суффикс, то при включенной жесткой проверке типов будет выдано сообщение об ошибке!

При использовании простого оператора / для деления в VB .NET необходимо учитывать некоторые нюансы. За дополнительной информацией обращайтесь к разделу «Математические операторы».

 

Строки

Строковая переменная содержит текст в кодировке Unicode длиной до 231 (более 2 миллиардов!) символов. Как было показано выше, значения строкового типа заключаются в кавычки:

Dim message As String

message = "Help"

Конкатенация (объединение) строк обычно выполняется оператором &. Старый вариант с оператором + тоже работает, но при отключении жесткой проверки типов он может вызвать серьезные проблемы, поэтому использовать знак + при конкатенации не рекомендуется. Старый способ идентификации строковых переменных с суффиксом $ (например, aStringVariableS) иногда используется для временных переменных.

В VB .NET строковые переменные не относятся к базовому типу, а являются экземпляра-ми класса String. Некоторые нюансы, связанные с их применением, будут рассмотрены в главе 4, а пока мы упомянем лишь одну особенность, о которой необходимо знать для эффективной работы со строками в VB .NET: при любой модификации строки в VB .NET создается новый экземпляр строки. Частая модификация строки требует больших затрат ресурсов, поэтому в VB .NET имеется класс StringBuilder для выполнения подобных операций (например, выборки данных из буфера и объединения их в строковой переменной).

В отличие от предыдущих версий VB, в VB .NET не поддерживаются строки фиксированной длины.

 

Строковые функции

В вашем распоряжении остались все классические строковые функции VB6 (Left, Right, Mid и т. д.), но версии этих функций с суффиксом $ теперь не поддерживаются. В табл. 3.5 перечислены важнейшие функции класса String, заменяющие строковые функции VB6. Не забывайте, что при многократной модификации строк (например, при вызове Mid в цикле) следует использовать класс StringBuilder, описанный в главе 4. Некоторые из приведенных методов используют массивы, которые будут рассмотрены ниже в этой главе.

При программировании для .NET рекомендуется по возможности использовать методы и свойства класса Stri ng, входящего в .NET Framework. Самые распространенные строковые методы перечислены в табл. 3.6.

Таблица 3.5. Основные строковые функции

Функция
Описание
Asc
Возвращает код первого символа в строке
Chr
Преобразует число в символ Unicode
Filter
Получает строковый массив и искомую строку; возвращает одномерный массив всех элементов, в которых был найден заданный текст
GetChar
Возвращает символ строки с заданным индексом в формате Char. Индексация символов начинается с 1. Например, команда GetChar("Hello",2) возвращает символ «е» в виде типа Char
InStr
Возвращает позицию первого вхождения одной строки в другой строке
InStrRev
Возвращает позицию последнего вхождения одной строки в другой строке
Join
Строит большую строку из меньших строк
LCase
Преобразует строку к нижнему регистру
Left
Находит или удаляет заданное количество символов от начала строки
Len
Возвращает длину строки
LTrim
Удаляет пробелы в начале строки
Mid
Находит или удаляет символы в строке
Replace
Заменяет одно или более вхождений одной строки в другой строке
Right
Находит или удаляет заданное количество символов в конце строки
RTrim
Удаляет пробелы в конце строки
Space
Генерирует строку заданной длины, состоящую из пробелов
Split
Позволяет разбивать строку по заданным разделителям (например, пробелам)
Str
Возвращает строковое представление числа
StrComp
Альтернативный способ сравнения строк
StrConv
Преобразует строку из одной формы в другую (например, с изменением регистра)
String
Создает строку, состоящую из многократно повторяющегося символа
Trim
Удаляет пробелы в начале и конце строки
UCase
Преобразует строку к верхнему регистру

 

Таблица 3.6. Основные строковые методы и свойства .NET Framework

Метод/свойство Описание
Chars Возвращает символ, находящийся в заданной позиции строки
Compare Сравнивает две строки
Copy Копирует существующую строку
Copy To Копирует заданное количество символов, начиная в заданную позицию массива символов
Empty Константа, представляющая пустую строку
EndsWith Проверяет, завершается ли заданная строка определенной последовательностью символов
IndexOf Возвращает индекс первого вхождения подстроки в заданной строке
Insert
Возвращает новую строку, полученную вставкой подстроки в заданную позицию
Join
Объединяет массив строк с заданным разделителем
LastlndexOf
Возвращает индекс последнего вхождения заданного символа или подстроки в строке
Length
Возвращает количество символов в строке
PadLeft
Выравнивает символы строки по правому краю. Строка дополняется слева пробелами или другими символами до заданной длины
PadRight
Выравнивает символы строки по левому краю. Строка дополняется справа пробелами или другими символами до заданной длины
Remove
Удаляет из строки заданное количество символов, начиная с заданной позиции
Replace
Заменяет все вхождения подстроки другой подстрокой
Split
Разбивает строку, превращая ее в массив подстрок
Starts With
Проверяет, начинается ли заданная строка определенной последовательностью символов
Substring
Возвращает подстроку, начинающуюся с заданной позиции
ToCharArray
Копирует символы строки в символьный массив
ToLower
Возвращает копию строки, преобразованную к нижнему регистру
ToUpper
Возвращает копию строки, преобразованную к верхнему регистру
Trim
Удаляет пробелы или все символы из набора, заданного в виде массива символов Unicode, в начале и конце строки
TrimEnd
Удаляет пробелы или все символы из набора, заданного в виде массива символов Unicode, в конце строки
TrimStart
Удаляет пробелы или все символы из набора, заданного в виде массива символов Unicode, в начале строки

 

В отличие от VB6, где индексация символов в строке начиналась с 1, в методах .NET Framework индекс первого символа равен 0.

Поскольку в .NET Framework строки являются объектам, синтаксис вызова этих методов достаточно логичен и удобен. Выполните следующую программу:

Sub Main()

Dim river As String =" Mississippi Missippi"

'один пробел слева

Consol e. Wri teLi ne( ri ver. Tollpper ())

Console.Wri teLi net ri ver.ToLower())

Console.WriteLineCriver.Trim())

Console. WriteLinetri ver. EndsWith("I"))

Consol e.Wri teLi ne С ri ver.EndsWith("i"))

Console.WriteLine(river.IndexOf("s"))

'Индексация начинается с 0!

Console.WriteLineCriver.Insert(9. " river"))

'Индексация

' начинается с 0!

Consol e.ReadLine() End Sub

Результат выглядит так:

MISSISSIPPI MISSIPPI

mississippi missippi

Mississippi Missippi

False

True

3

Mississi riverppi Missippi