В современных версиях Delphi, начиная с версии 2010 (Tokyo), была добавлена поддержка RTTI (Run-Time Type Information) для записей. Это позволяет разработчикам итерироваться по полям записи на лету, что может быть очень удобно при работе с динамическими данными.
Пример использования RTTI
Для итерации по полям записи можно использовать следующий пример кода:
program Project1;
{$APPTYPE CONSOLE}
uses
System.Rtti;
type
TvatIndividual = record
DocumentNumber: string;
TurnoverDate: TDate;
PaymentDate: TDate;
DocumentType: string;
Year: integer;
TurnoverDescription: string;
TurnoverAmount: Currency;
end;
begin
for var f in TRttiContext.Create.GetType(TypeInfo(TvatIndividual)).GetFields do
WriteLn(f.ToString);
ReadLn;
end.
В этом коде используется класс TRttiContext для получения информации о типах. Метод GetType возвращает объект Type, который представляет собой тип записи TvatIndividual. Затем, с помощью свойства GetFields, мы получаем список всех полей этого типа.
Получение имен и типов полей
Чтобы получить имена и типы полей, можно модифицировать пример следующим образом:
program Project1;
{$APPTYPE CONSOLE}
uses
System.Rtti;
type
TvatIndividual = record
DocumentNumber: string;
TurnoverDate: TDate;
PaymentDate: TDate;
DocumentType: string;
Year: integer;
TurnoverDescription: string;
TurnoverAmount: Currency;
end;
begin
for var f in TRttiContext.Create.GetType(TypeInfo(TvatIndividual)).GetFields do
Writeln(Format('Имя поля: %s, Тип поля: %s', [f.Name, f.FieldType.TypeName]));
ReadLn;
end.
В этом случае в цикле используется функция Format для вывода имени и типа каждого поля.
Альтернативные подходы
Если по каким-то причинам использование RTTI не желательно или невозможно (например, из-за ограничений совместимости с более старыми версиями Delphi), можно использовать рефлексию через интерфейс IInvariant.
uses
Typinfo;
type
PFieldInfo = ^TFieldInfo;
TFieldInfo = record
Name: string;
// Другие поля, которые могут быть нужны для работы с полями типа.
end;
function GetFields(const ATypeInfo: PTYPEINFO): array of TFieldInfo;
var
CurRec: PFieldInfo;
NewRec: Pointer;
begin
SetLength(Result, TypeInfo(ATypeInfo).Cmp, SizeOf(TFieldInfo) + TypeInfo(ATypeInfo).TypeData[0].NameLen);
CurRec := @Result[0];
with CurRec^ do
Name := TypeInfo(ATypeInfo).TypeData[0].Name;
NewRec := GetMem(TypeInfo(PFieldInfo), TypeInfo(ATypeInfo).Cmp);
try
for var i := 1 to TypeInfo(ATypeInfo).NCount - 1 do
with CurRec^ do
Name := CopyAnsiStr(@TypeInfo(ATypeInfo).TypeData[i].Name[0]);
NewRec := Typinfo.GetPropInfo(TypeInfo(ATypeInfo), i, NewRec^, 0);
if (CurRec = nil) then
SetLength(Result, 1);
CurRec := NewRec;
Result[High(Result)]^.Name := '';
finally
FreeMem(NewRec, TypeInfo(ATypeInfo).Cmp);
end;
end;
var
TypeRec: TvatIndividual;
FieldInfos: array of TFieldInfo;
begin
SetLength(FieldInfos, TypeInfo(TypeInfo(TvatIndividual)).NCount - 1);
GetFields(@TypeInfo(TvatIndividual), FieldInfos[0]);
for var Field in FieldInfos do
Writeln('Имя поля: ' + Field.Name);
end.
Обратите внимание, что такой код требует более глубокого понимания работы с типами и их информацией в Delphi.
Заключение
может быть выполнена с помощью RTTI, начиная с версии 2010. Это позволяет разработчикам работать с записями как с динамическими структурами данных, что значительно упрощает многие задачи обработки данных. В случае необходимости можно использовать альтернативные подходы, такие как рефлексия через IInvariant, но они требуют более глубокого понимания механизмов работы с типами в Delphi.
Предоставляется описание того, как выполняется итерация по полям записи в Delphi с использованием RTTI, включая примеры кода для демонстрации различных способов извлечения информации о записях.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.