gpt4 book ai didi

Delphi 字典保存/加载。 TDictionary 不可序列化?

转载 作者:行者123 更新时间:2023-12-03 18:18:01 32 4
gpt4 key购买 nike

TDictionary : SaveToFile/LoadFromFile

多么优雅的解决方案!首先,一切都按预期运行。

内容以看起来正确的 JSON 格式保存到文件中。但是重新加载文件后,出现了问题:

Type
TEnumCategTypes = ( e_SQL1, e_VBA, e_Text );
TCategParams = class
fontStyles : TFontStyles;
rgbColor : COLORREF;
end;

TdictCategory = class ( TDictionary<TEnumCategTypes, TCategParams> )
public
public class function LoadFromFile( const AFileName: string ): TdictCategory;
public class procedure SaveToFile( const AFileName: string; dict: TdictCategory );
end;

implementation

class procedure TdictCategory.SaveToFile( const AFileName: string; dict: TdictCategory );
var
stream : TStringStream;
begin
try
stream := TStringStream.Create( TJson.ObjectToJsonString( dict ) ) ;
stream.SaveToFile( AFileName )
finally
stream.Free;
end;
end;
//---
class function TdictCategory.LoadFromFile( const AFileName: string ): TdictCategory;
var
stream: TStringStream;
begin
stream := TStringStream.Create;
try
stream.LoadFromFile( AFileName );
result := TJson.JsonToObject<TdictCategory>( stream.DataString );
finally
stream.Free;
end;
end;

测试如下。所有的荣耀都结束了。这是代码,包括注释:

..
var
cc: Colorref;
begin
.. // fill values
cc := DictCategory.Items[ e_SQL1 ].rgbColor; // Okay, it works
TdictCategory.SaveToFile( 'category.json', DictCategory ); // Even the contents of the file, looks good
DictCategory.Clear;
DictCategory.Free;
DictCategory := nil;
DictCategory := TdictCategory.LoadFromFile( 'category.json' ); // DictCategory is no longer NIL, and it looks optically well..
cc := DictCategory.Items[ e2_sql_aggregate ].rgbColor; // C R A S H !!! with AV

好像是Delphi(Berlin 10.1),不能序列化Dictionary!如果那是真的,我真的很伤心。我相信还有很多其他人。还是附件代码有错误?

最佳答案

TJson.JsonToObject最终将使用默认构造函数实例化对象(请参阅 REST.JsonReflect.TJSONUnMarshal.ObjectInstance)。

现在查看System.Generics.Collections你会看到 TDictionary<TKey,TValue>没有默认构造函数(不,RTTI 没有关于参数默认值的信息,因此不会考虑带有 Capacity: Integer = 0 的构造函数)。

这意味着 RTTI 将进一步查找并找到 TObject.Create并在字典类上调用它,这将为您留下一个半初始化的对象(如果没有运行您的代码,我猜它的 FComparer 没有被分配 TDictionary<TKey,TValue> 的构造函数会完成)。

长话短说:向您的 TdictCategory 添加一个无参数构造函数然后调用inherited Create;那里。那么TJSONUnMarshal.ObjectInstance将找到无参数构造函数并调用拥有正确初始化实例所需的所有代码。

无论如何,您可能不会对结果感到满意 REST.JsonReflect简单地序列化实例的所有内部状态(除非通过未在 RTL 类中完成的属性明确排除),因此也反序列化它们,这意味着此类 JSON 仅兼容 Delphi 到 Delphi。

关于Delphi 字典保存/加载。 TDictionary 不可序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47835779/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com