【问题标题】:In a Delphi TDictionary, my Value objects are inserting as null在 Delphi TDictionary 中,我的 Value 对象插入为 null
【发布时间】:2010-08-18 16:34:25
【问题描述】:

我正在使用 Delphi 9 的 TDictionary 泛型类。我的 TDictionary 如下所示:

g_FileHandlers : TDictionary<String, TList<String>>;

然后,我像这样初始化 TDictionary:

g_FileHandlers := TDictionary<String, TList<String>>.Create;

我有一个 TList,我也在初始化它,以便我可以使用它来填充 TDictionary。我正在循环一些用于填充 TList/TDictionary 的文件数据,并且我试图重新使用相同的 TList 作为值插入到 TDictionary 中。在第一次插入 TDictionary 时,项目的 TList 值存在并且其中包含数据。在第二次和随后的迭代中,尽管 TList 值全部为零。

g_FilePaths := TList<String>.Create;

在我看来,这一切都是通过引用来完成的。如何按值而不是引用将 TList 添加到我的 TDictionary?

  // Create our dictionary of files and handlers
  for i := 0 to g_FileList.Count - 1 do
  begin
    g_HandlerName := AnsiMidStr(g_FileList[i], 2, Length(g_FileList[i]));
    g_HandlerName := AnsiMidStr(g_HandlerName, 1, Pos('"', g_HandlerName) - 1);

    if i = 0 then
      g_PreviousHandlerName := g_HandlerName;

    if AnsiCompareText(g_HandlerName, g_PreviousHandlerName) = 0 then
    begin
      g_FilePath := AnsiMidStr(g_FileList[i], Length(g_HandlerName) + 5, Length(g_FileList[i]));
      g_FilePath := AnsiMidStr(g_FilePath, 1, Length(g_FilePath) - 1);
      g_FilePaths.Add(g_FilePath);
    end
    else
    begin
      g_FileHandlers.Add(g_PreviousHandlerName, g_FilePaths);

      g_FilePaths.Clear;
      g_FilePath := AnsiMidStr(g_FileList[i], Length(g_HandlerName) + 5, Length(g_FileList[i]));
      g_FilePath := AnsiMidStr(g_FilePath, 1, Length(g_FilePath) - 1);
      g_FilePaths.Add(g_FilePath);
    end;

    if AnsiCompareText(g_HandlerName, g_PreviousHandlerName) <> 0 then
      g_PreviousHandlerName := g_HandlerName;

    if i = g_FileList.Count - 1 then
      g_FileHandlers.Add(g_HandlerName, g_FilePaths);
  end;
  g_FilePaths.Free;

【问题讨论】:

    标签: delphi tlist tdictionary


    【解决方案1】:

    您拥有的 TList“值”一个引用,因此您 正在按值添加它。 (通过引用添加意味着如果您更改了 g_FilePaths 的值,存储在字典中的值也会更改,但这不会发生 - 这些值继续引用它们开始时使用的同一 TList 对象。

    TDictionary 不会像其他任何东西一样制作对象的深层副本。您只需要硬着头皮为要添加的每个项目创建一个新的 TList 对象。您可以根据需要重复使用全局变量g_FilePaths,但每次迭代都需要实例化一个新对象。

    【讨论】:

    • 我同意并且还想建议 OP 使用 TObjectDictionary 并使用 "TObjectDictionary>.Create([doOwnsValues]);" 创建避免删除项目时列表的内存泄漏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    相关资源
    最近更新 更多