Значимые и ссылочные типы, преобразования
Глава про VB.NET. Базовые типы и
Option Strict— в типах данных.
Как читать эту статью
Короткая глава: таблица value и reference → CType / TryCast → Nothing и nullable. Читайте после типов и перед управлением.
Value и reference types в VB.NET
Путаница между копированием структуры и ссылкой на объект — частая причина багов в VB.NET и при interop с COM.
Value и reference types - зачем разделять
В управляемой среде .NET переменная хранит либо само значение (число, символ, структура), либо ссылку на объект в куче. От этого зависят копирование, сравнение, Nothing и ошибки «приведение невозможно».
| Категория | Примеры | Где живёт экземпляр | Пустое состояние |
|---|---|---|---|
Значимый (Structure, примитив) | Integer, Date, Decimal, своя Structure Point | Обычно в стеке или внутри объекта | Нет «пустого» Integer; есть Integer? |
Ссылочный (Class, String, массив) | String, List(Of T), Form | Управляемая куча | Nothing |
String — ссылочный тип, но ведёт себя как неизменяемое значение: операции создают новую строку.
Копирование и сравнение
' Значимые типы копируются по значению
Dim a As Integer = 10
Dim b As Integer = a
b = 20
' a остаётся 10
' Ссылочные — копируется адрес
Dim list1 As New List(Of String)
list1.Add("A")
Dim list2 As List(Of String) = list1
list2.Add("B")
' list1 тоже содержит "A" и "B"
Для ссылочных типов оператор Is проверяет один и тот же объект в памяти, а = для классов по умолчанию сравнивает ссылки (если не переопределён Equals).
Dim x As New List(Of Integer)
Dim y As List(Of Integer) = x
Console.WriteLine(x Is y) ' True
Console.WriteLine(x Is Nothing) ' False
Structure и Class
Structure | Class | |
|---|---|---|
| Назначение | Небольшие наборы полей (точка, RGB, интервал) | Сущности с поведением и жизненным циклом |
| Наследование | Только интерфейсы | Классы и интерфейсы |
| Передача в процедуру | По значению (копия) | По ссылке |
Nothing | Не применяется к самой структуре в переменной | Обнуляет ссылку |
Structure Point2D
Public X As Double
Public Y As Double
End Structure
Dim p As Point2D
p.X = 1
p.Y = 2
Для моделей предметной области (Order, Customer) почти всегда выбирают Class.
Упаковка и распаковка
Если значимый тип положить в Object, CLR выполняет boxing — создаёт объект-обёртку в куче. Обратное извлечение — unboxing с явным типом.
Dim boxed As Object = 42
Dim value As Integer = CType(boxed, Integer)
Частые boxing-источники: старые коллекции ArrayList, параметры Object, некоторые перегрузки API. В новом коде предпочтительны List(Of T) и обобщённые методы — меньше лишних аллокаций.
Неявные и явные преобразования
Расширяющие (без потери данных) допускаются неявно, если не мешает Option Strict On:
Dim count As Integer = 10
Dim rate As Double = count ' Integer → Double
Сужающие требуют явного приведения:
Dim price As Double = 19.99
Dim units As Integer = CInt(Math.Floor(price))
При Option Strict On такие присваивания без CInt / CType не компилируются — это защита от тихих округлений.
CType, DirectCast, TryCast
| Оператор | Когда использовать |
|---|---|
CType(expr, T) | Известные совместимые типы, числовые преобразования, вызов пользовательских операторов Widening/Narrowing |
DirectCast(expr, T) | Ссылочные типы в иерархии; если объект не того типа — исключение |
TryCast(expr, T) | Безопасно: при неудаче вернёт Nothing вместо исключения |
Dim obj As Object = "hello"
Dim text As String = TryCast(obj, String) ' "hello"
Dim num As Integer? = TryCast(obj, Integer) ' Nothing
Dim control As Control = DirectCast(obj, Control) ' InvalidCastException для строки
TypeOf и Is
If TypeOf sender Is Button Then
Dim btn = DirectCast(sender, Button)
btn.Enabled = False
End If
TypeOf … Is не бросает исключение при Nothing.
Nothing, nullable и DBNull
Nothingдля ссылочного типа — «ссылки нет». ДляStringэто не то же самое, что"".Integer?и другиеT?— «значение отсутствует» черезHasValue/Nothing.DBNull.Value— отдельный маркер из ADO.NET при чтенииNULLиз БД; сравнивайте черезIsDBNull, не смешивайте сNothingбез проверки.
Dim age As Integer? = Nothing
If age.HasValue Then
Console.WriteLine(age.Value)
Else
Console.WriteLine("возраст не указан")
End If
Оператор If с тремя аргументами удобен для nullable:
Dim displayAge = If(age.HasValue, age.Value.ToString(), "н/д")
Практические правила
- Включайте
Option Strict Onв учебных и новых проектах. - Не храните числа в
Object«на всякий случай» — выбирайте конкретный тип или обобщениеOf T. - Для иерархии классов —
TryCast+ проверка наNothing, для чисел —CType/CIntс пониманием округления. - Деньги и координаты в бизнес-логике —
Decimal/Structure, а неDouble, если важна точность.
Что дальше
| Тема | Статья |
|---|---|
Примитивы, Option Strict | Типы |
If, циклы | 5 |
| Коллекции, файлы | 10 |
| Архитектура .NET | 3 |
Что попробовать
- Скопируйте
Structureв две переменные — измените поле в одной и сравните. - Присвойте
Nothingссылочной переменной и проверьтеIs Nothing. - Используйте
Integer?иHasValueдля необязательного поля формы.
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). История Visual Basic - эволюция от BASIC до современных реализаций в экосистеме Microsoft. Практика VB.NET — консольные программы, dotnet CLI, выбор коллекций и чтение/запись файлов через BCL. VB.NET — лямбда-выражения, Func/Action, LINQ, перегрузка операторов, индексаторы и IEnumerable для For Each. Основы языка Visual Basic - синтаксис, базовые конструкции и роль VB в обучении программированию. Архитектура приложений на Visual Basic - структура проекта, компоненты и подходы к построению Windows-приложений. Типизация, набор правил определения типа данных значений языка. Управляющие конструкции и операторы Visual Basic - условные блоки, циклы и выражения в прикладном коде. Процедуры и события в Visual Basic - обработчики, жизненный цикл событий и организация прикладной логики. Гайд по установке и настройке с написанием первой программы и её запуском. Справочник-шпаргалка по visual-basic — типы, синтаксис, стандартная библиотека, типовые паттерны. Не заменяет пошаговое обучение. Учебный курс — раздел. Краткий ввод в Visual Basic for Applications — макросы, объектная модель Excel и отличия от VB.NET. Краткие итоги раздела «Visual Basic».История языка visual-basic
Консоль и файлы
Лямбды и LINQ
Основы языка visual-basic
Архитектура приложений на visual-basic
Типы данных в visual-basic
Управляющие конструкции и операторы visual-basic
Процедуры и события в visual-basic
Первая программа на visual-basic
Справочник по visual-basic
VBA в Excel
Итоги