В работе с системой RTTI (Run-Time Type Information) в Delphi часто возникает необходимость проверки типов данных, особенно при использовании универсального типа TValue. В этой статье мы рассмотрим несколько способов проверки, является ли значение TValue массивом значений TValue.
Введение в проблему
Тип TValue из модуля System.Rtti представляет собой универсальный контейнер для хранения значений любого типа. Иногда требуется определить, содержит ли TValue массив других значений TValue.
Базовое решение
Наиболее простой способ проверки - сравнение TypeInfo:
function ValueIsArrayOfValues(const V: TValue): Boolean;
begin
Result := V.TypeInfo = TypeInfo(TArray<TValue>);
end;
Это решение работает только для динамических массивов TArray<TValue> (которые являются псевдонимом для array of TValue).
Универсальное решение для всех типов массивов
Для более универсального решения, которое работает с любыми типами массивов (статическими, динамическими, многомерными), можно использовать следующий подход:
function ValueIsValueArray(const V: TValue): Boolean;
function GetArrayElType: PTypeInfo;
var
ref: PPTypeInfo;
begin
Result := nil;
case V.Kind of
tkArray:
ref := V.TypeData^.ArrayData.ElType;
tkDynArray:
ref := V.TypeData^.DynArrElType;
else
Exit;
end;
if ref <> nil then
Result := ref^;
end;
begin
Result := V.IsArray and (GetArrayElType() = TypeInfo(TValue));
end;
Разбор решения:
V.IsArray - проверяет, является ли значение массивом любого типа
GetArrayElType() - вспомогательная функция, которая получает тип элементов массива
Сравнение с TypeInfo(TValue) - проверяет, что элементы массива имеют тип TValue
Альтернативные подходы
Для статических массивов
Если вам нужно работать только со статическими массивами:
function IsStaticArrayOfTValues(const V: TValue): Boolean;
begin
Result := (V.Kind = tkArray) and
(V.TypeData^.ArrayData.ElType^ = TypeInfo(TValue));
end;
Для динамических массивов
Для работы только с динамическими массивами:
function IsDynamicArrayOfTValues(const V: TValue): Boolean;
begin
Result := (V.Kind = tkDynArray) and
(V.TypeData^.DynArrElType^ = TypeInfo(TValue));
end;
Пример использования
procedure TestArrayCheck;
var
ValueArr: TArray<TValue>;
IntArr: TArray<Integer>;
Value: TValue;
begin
// Создаем массив TValue
ValueArr := [TValue.From(1), TValue.From('test'), TValue.From(3.14)];
// Проверяем массив TValue
Value := TValue.From(ValueArr);
if ValueIsValueArray(Value) then
WriteLn('Это массив TValue')
else
WriteLn('Это не массив TValue');
// Проверяем массив Integer
IntArr := [1, 2, 3];
Value := TValue.From(IntArr);
if ValueIsValueArray(Value) then
WriteLn('Это массив TValue')
else
WriteLn('Это не массив TValue');
end;
Заключение
В зависимости от ваших потребностей, вы можете выбрать подходящий метод проверки: - Простое сравнение TypeInfo для динамических массивов - Универсальное решение для всех типов массивов - Специализированные решения для статических или динамических массивов
Универсальное решение, предложенное Remy Lebeau, является наиболее надежным, так как работает со всеми типами массивов и правильно обрабатывает вложенные типы.
Проверка, является ли значение TValue массивом значений TValue в Delphi.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.