Я исправил это, реализовав метод DefineProperties в моем потомке TPersistent. Я хотел сделать общее решение этой проблемы, которое я мог бы легко реализовать во всех моих объектах для всех соответствующих свойств. Вот как это выглядит:
TOverridePropFiler = class
private
FReadWritePropName: string;
FObject: TObject;
procedure ReadOverrideProp(Reader: TReader);
procedure WriteOverrideProp(Writer: TWriter);
public
constructor Create(Filer:TFiler; Obj:TObject; Name:string);
end;
{ TOverridePropFiler }
constructor TOverridePropFiler.Create(Filer:TFiler; Obj:TObject; Name:string);
begin
FReadWritePropName:=Name;
FObject:=obj;
if (Name='') or not Assigned(GetPropInfo(Obj,Name)) then
Raise Exception.CreateFmt('Property %s not found in object %s',[Name,Obj.ClassName]);
Filer.DefineProperty(Name, ReadOverrideProp, WriteOverrideProp,
GetPropValue(FObject,FReadWritePropName,False)<>uiFloat);
end;
procedure TOverridePropFiler.ReadOverrideProp(Reader: TReader);
begin
SetPropValue(FObject,FReadWritePropName,Reader.ReadFloat);
end;
procedure TOverridePropFiler.WriteOverrideProp(Writer: TWriter);
begin
Writer.WriteDouble(GetPropValue(FObject,FReadWritePropName,False));
end;
Я вызываю его в моем методе DefineProperties следующим образом:
procedure TMyObj.DefineProperties(Filer: TFiler);
begin
inherited;
TOverridePropFiler.Create(Filer,Self,'dTOverride').Free;
end;
Чтобы сделать это обобщенным, мне пришлось использовать RTTI и локально сохранить имя свойства (это невозможно получить из TWriter, и требуется взлом для TReader). Чтобы сделать его потокобезопасным (и поскольку TFiler.DefineProperty хочет функции «объекта»), я инкапсулировал все это в объекте.
В моем случае я хочу, чтобы значением по умолчанию было uiFloat. Эта константа может быть установлена на то, что вы хотите. Если вам нужны разные значения по умолчанию для разных свойств, вы можете легко добавить значение по умолчанию в качестве параметра в функцию Create.
Обратите внимание, что в конструкторе TMyObj все еще необходимо установить свойство по умолчанию.
Мне кажется, это довольно эффективный способ обойти довольно серьезное ограничение в Delphi.
Редактировать: Вы должны помнить, чтобы добавить «сохраненное ложное» во все свойства, которые используют это.