Вопрос, с которым сталкиваются разработчики, использующие расширенное RTTI (Runtime Type Information) в многопоточных приложениях на Delphi, заключается в необходимости получения списка свойств только текущего класса, исключая наследуемые. В частности, в контексте использования класса TPersistent и его потомков, где некоторые свойства должны быть доступны для чтения, а некоторые - нет.
Проблема
Расширенное RTTI предоставляет функцию GetDeclaredProperties, которая позволяет получить список свойств, объявленных в текущем классе. Однако, использование этой функции в многопоточной среде может привести к проблемам. В качестве альтернативы, функция GetPropList возвращает список всех свойств, включая наследуемые, что не соответствует требованиям задачи.
В примере, представленном ниже, имеются несколько классов, наследующих друг друга, и требуется получить список свойств текущего класса без учета наследуемых.
TBaseSettings = class(TPersistent)
published
property Charset: string read FCharset write FCharset;
end;
TBasicSettings = class(TBaseSettings)
published
property forums: Variant read fforums write fforums;
end;
TConcreteSettings = class(TBasicSettings)
published
property forums; // явное указание видимости: OK
property prefix: Variant read fprefix write fprefix; // OK
end;
Необходимо получить список свойств, исключая свойство Charset, которое не должно быть прочитано.
Решение
Исходя из контекста, было предложено несколько подходов к решению проблемы. Один из комментаторов предложил изменить тип доступа свойств в базовом классе на public, что позволит исключить их из списка свойств, возвращаемых функцией GetPropList.
Также был представлен код, который позволяет использовать функционал GetDeclaredPropList аналогично GetPropList. Этот код должен быть адаптирован для работы в среде Delphi 2010, так как в нем используются некоторые особенности, отсутствующие в этом релизе (например, функции TTypeData.PropData и TPropInfo.Tail).
// Код функции GetDeclaredPropList и сопутствующих функций
Пример использования
var
I, Count: Integer;
PropList: PPropList;
PropInfo: PPropInfo;
begin
Count := GetDeclaredPropList(TypeInfo(TConcreteSettings), PropList);
try
for I := 0 to Count - 1 do
begin
PropInfo := PropList^[I];
Writeln(PropInfo^.Name);
end;
finally
FreeMem(PropList);
end;
end.
Заключение
В данной статье был рассмотрен вопрос получения свойств текущего класса с использованием расширенного RTTI в многопоточной среде. Представлены различные подходы к решению этой задачи, включая изменение типа доступа свойств и использование кастомной реализации функции GetDeclaredPropList. Важно отметить, что для корректной работы в среде Delphi 2010, код может потребовать дополнительной адаптации.
Вопрос касается получения свойств текущего класса в многопоточной среде с использованием расширенного RTTI в Delphi, исключая наследуемые свойства.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS