При работе с классами в программировании на Delphi иногда возникает необходимость в динамическом сбросе значений свойств. Например, для строковых свойств это может быть пустая строка, а для булевых — ложное значение. В данной статье рассмотрим, как можно реализовать такую функциональность, используя возможности языка Object Pascal и библиотеки RTTI (Runtime Type Information), которая позволяет работать с типами и свойствами объектов во время выполнения программы.
Проблема
Разработчик столкнулся с задачей динамического сброса всех строковых свойств в пустую строку и булевых свойств в False для класса в своем приложении на Delphi. На просторах интернета он нашел упоминания о возможности использования циклов, но конкретный способ реализации не был ясен.
Решение
В версиях Delphi 2010 и выше доступна новая единица RTTI (rtti.pas), которая позволяет получать информацию о классе и его свойствах во время выполнения программы. Для демонстрации рассмотрим класс TTest с тремя публичными свойствами: двумя строковыми и одним булевым.
Для перебора свойств объекта и установки их значений по умолчанию можно использовать следующий подход:
TObjectReset = record
strict private
public
class procedure ResetObject(obj: TObject); static;
end;
class procedure TObjectReset.ResetObject(obj: TObject);
var
ctx: TRttiContext;
rt: TRttiType;
prop: TRttiProperty;
value: TValue;
begin
ctx := TRttiContext.Create();
try
rt := ctx.GetType(obj.ClassType);
for prop in rt.GetProperties() do begin
if not prop.IsWritable then continue;
case prop.PropertyType.TypeKind of
tkEnumeration: value := False;
tkUString: value := '';
else continue;
end;
prop.SetValue(obj, value);
end;
finally
ctx.Free();
end;
end;
Дополнительно, можно использовать атрибуты для обозначения свойств, которые необходимо сбрасывать, и указания их начальных значений.
Альтернативный ответ
Для версий Delphi старше Delphi 2009, которые не поддерживают tkUString, необходимо удалить соответствующую часть кода. Также важно помнить, что данный метод работает только для опубликованных свойств класса.
Вот пример функции, которая сбрасывает значения опубликованных свойств:
uses
TypInfo;
procedure ResetPropertyValues(const AObject: TObject);
var
PropIndex: Integer;
PropCount: Integer;
PropList: PPropList;
PropInfo: PPropInfo;
TypeKinds: TTypeKinds = [tkEnumeration, tkString, tkLString, tkUString, tkWString];
begin
PropCount := GetPropList(AObject.ClassInfo, TypeKinds, nil);
GetMem(PropList, PropCount * SizeOf(PPropInfo));
try
GetPropList(AObject.ClassInfo, TypeKinds, PropList);
for PropIndex := 0 to PropCount - 1 do
begin
PropInfo := PropList^[PropIndex];
if Assigned(PropInfo^.SetProc) then
case PropInfo^.PropType^.Kind of
tkString, tkLString, tkUString, tkWString:
SetStrProp(AObject, PropInfo, '');
tkEnumeration:
if GetTypeData(PropInfo^.PropType^)^.BaseType^ = TypeInfo(Boolean) then
SetOrdProp(AObject, PropInfo, 0);
end;
end;
finally
FreeMem(PropList);
end;
end;
Используя приведенные выше примеры, разработчик может динамически сбрасывать значения свойств класса в Delphi, что может быть полезно в различных сценариях, таких как сброс состояния формы или подготовка объекта к повторному использованию.
Разработчик в Delphi нуждается в динамическом сбросе строковых и булевых свойств класса, что можно реализовать с использованием RTTI для получения информации о свойствах и их изменении во время выполнения программы.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.