Nullable-типы

Что такое nullable-типы и зачем они нужны в Delphi?
Nullable-типы (типы, допускающие неопределённое значение) решают классическую проблему: как отличить «ноль» от «значения нет». В Delphi 2026 года разработчику доступно несколько путей реализации этой концепции. Каждый вариант имеет особенности, влияющие на производительность, читаемость кода и совместимость с базами данных.
Сравнение подходов: три основных варианта
1. Встроенные nullable-типы (System.Nullable)
Стандартный механизм, появившийся в современных версиях Delphi (начиная с 10.x). Позволяет объявить переменную, которая может быть либо значением базового типа, либо пустой ссылкой (nil).
- Особенность: использует generic-тип
Nullable. - Плюсы: единообразие, встроенная поддержка операторов сравнения, автоматическая упаковка/распаковка.
- Минусы: накладные расходы на упаковку значений-типов, невозможность прямого наследования.
2. Записи с флагом IsNull (самодельный подход)
Классический метод, распространённый в проектах, где важна совместимость со старыми версиями Delphi (до XE). Создаётся запись, содержащая поле для значения и булевый флаг, указывающий, задано ли значение.
- Особенность: полностью ручное управление.
- Плюсы: полный контроль, минимум накладных расходов, отсутствие зависимости от версии компилятора.
- Минусы: требуется реализовывать все операторы и методы доступа; код становится громоздким.
3. Использование Variant и Null
Старый способ, при котором переменная типа Variant может принимать специальное значение Null. Иногда встречается в коде, работающем с базами данных (BDE, ADO).
- Особенность: динамическая типизация.
- Плюсы: простота, встроенная поддержка Null в запросах.
- Минусы: замедление работы на порядки из-за упаковки; потеря строгой типизации; высокий риск ошибок времени выполнения.
Таблица сравнения характеристик
| Критерий | System.Nullable | Запись с флагом IsNull | Variant + Null |
|---|---|---|---|
| Строгая типизация | Да | Да (на уровне записи) | Нет |
| Производительность | Средняя (упаковка) | Высокая | Низкая |
| Совместимость с БД | Хорошая (через преобразование) | Требуется адаптер | Прямая |
| Читаемость кода | Высокая | Средняя (требуются проверки) | Низкая (неявные преобразования) |
| Минимальная версия Delphi | 10 Seattle (2015) | Любая | Все версии |
| Риск ошибок | Низкий | Средний (ручные проверки) | Высокий |
Кому какой вариант подходит?
- System.Nullable — выбор для новых проектов на Delphi 2026, где важна чистота кода и поддержка сообществом. Идеально подходит для команд, использующих современные архитектуры (MVVM, DataSnap). Не рекомендуется для высоконагруженных вычислительных задач или встраиваемых систем.
- Запись с флагом IsNull — незаменим при поддержке legacy-проектов, написанных для Delphi 7–2007. Подойдёт разработчикам, которым нужен максимальный контроль над памятью и производительностью (драйверы, обработка потоков). Не рекомендуется для новичков из-за объёмного кода.
- Variant + Null — только для быстрых прототипов или работы с устаревшими библиотеками (например, старые компоненты доступа к базам). Категорически не подходит для крупных проектов, где важна отладка и типизация.
Рекомендации при выборе
- Если проект начинается с нуля на Delphi 10.3 или новее — используйте
Nullable. - Если код должен работать на Delphi 7–XE — выбирайте запись с флагом IsNull.
- Избегайте Variant для nullable-логики везде, кроме случаев, когда уже используется смешанная типизация в легаси.
- Для работы с базами данных используйте специализированные поля (TField.IsNull) и не смешивайте их с nullable-типами языка.
В 2026 году стандартные nullable-типы становятся де-факто стандартом, но знание альтернатив помогает эффективно решать задачи на разных этапах жизненного цикла приложения.
Добавлено: 27.04.2026
