【问题标题】:How to Sort Sections on TMemIniFile如何对 TMemIniFile 上的部分进行排序
【发布时间】:2016-09-15 04:06:59
【问题描述】:

我正在使用 TMemIniFile 来存储配置,我需要按 alpha 顺序对部分进行排序。

为此,我创建了 TMemIniFile 的后代

  TRWStudioMemIniFile = class(TMemIniFile)
  public
    procedure UpdateFile; override;
    procedure GetSortedStrings(List: TStrings);
  end;


{ TRWStudioMemIniFile }

procedure TRWStudioMemIniFile.GetSortedStrings(List: TStrings);
var
  I, J: Integer;
  Strings: TStrings;
begin
  List.BeginUpdate;
  try
    Sections.Sort;
    for I := 0 to Sections.Count - 1 do
    begin
      List.Add('[' + Sections[I] + ']');
      Strings := TStrings(Sections.Objects[I]);
      for J := 0 to Strings.Count - 1 do List.Add(Strings[J]);
      List.Add('');
    end;
  finally
    List.EndUpdate;
  end;
end;

procedure TRWStudioMemIniFile.UpdateFile;
var
  List: TStringList;
begin
  List := TStringList.Create;
  try
    GetSortedStrings(List);
    List.SaveToFile(FileName, Encoding);
  finally
    List.Free;
  end;
end;

但它需要访问Sections(实际上是FSections:TStringList,即TMemIniFile的私有成员)

我创建了一个 Helper 类来通过属性公开该成员。但是,Delphi 10.1 不再支持此行为

我开始将 TMemIniFile 复制/粘贴到我的单元,经过无休止的过程,我最终制作了整个 System.IniFile 的副本,只是为了访问 FSections。

我的问题是如何访问该 FSections 成员,而无需复制该单元的所有内容来获得可见性

或者是否有另一种方法可以在保存之前对部分进行排序? (我只是从 FSections 调用 TStringList.Sort)

【问题讨论】:

  • 如何创建一个TMemIniFile 的新实例并按照您想要的顺序将各个部分一一添加?
  • 顺序在 ini 文件中并不重要。为什么你需要这样做。
  • 顺序在 ini 文件中通常并不重要,但有时它可能很重要:为了可读性、文档,或者只是为了保持排序以满足客户的需求。它是一种文本格式是有原因的 - 可供人类阅读/编辑。
  • 如果你想走这条路,可以在RTTI的帮助下得到私人成员FSections的地址。
  • @DavidHeffernan 因为我的老板要求这样做,还需要什么?

标签: oop delphi delphi-10.1-berlin


【解决方案1】:

您可以使用继承的ReadSections() 方法将这些部分放入您自己的TStringList,根据需要对该列表进行排序,然后使用继承的方法,而不是依赖类型转换和“破解”私有成员ReadSectionValues() 方法读取每个部分的字符串:

var
  sections: TStringList;
  values: TStringList;
begin
  sections := TStringList.Create;
  try
    ReadSections(sections);
    sections.Sort;

    values := TStringList.Create;
    try
      List.BeginUpdate;
      try
        for I := 0 to sections.Count - 1 do
        begin
          List.Add('[' + sections[I] + ']');

          values.Clear; // Just in case
          ReadSectionValues(sections[i], values);

          for J := 0 to values.Count - 1 do
            List.Add(values[J]);
          List.Add('');
        end;
      finally
        List.EndUpdate;
      end;
    finally
      values.Free;
    end;
  finally
    sections.Free;
  end;
end;

【讨论】:

  • 致于谁将他们的个人风格强加于代码并删除了 [imho] 关于从 OP 引用现有对象到需要创建/释放对象的变化的重要 cmets: 如果您可以请我参考官方“StackOverflow Delphi 编码标准”,我很乐意在未来的任何答案中遵守该标准。如果不是,那么请务必提出改进建议或 cmets(这就是他们的目的),或者如果您认为您的方法本质上不同且优越,那么请务必将其发布为不同的答案。否则,请保持你自己的双手。
  • 您对try..finally 的使用不是“风格”或“编码标准”的问题。从某种意义上说,它只是客观地错误出于资源保护的目的,它被错误地使用了。即使您的代码只是“演示性”,它也无助于树立坏榜样。除此之外,出于某种原因,问题是可以公开编辑的。当您为本网站做出贡献时,您的作品进入公共领域。
  • 不是公共领域,@Craig。创作共用。请参阅服务条款的第 3 节。 Deltics,您加入本网站已有七年多了。如果这是你第一次编辑你的贡献,我很抱歉,但现在真的不应该让你感到惊讶。编辑其他人的帖子的能力是创建 Stack Overflow 的主要原因之一。如果您想恢复已删除的段落,请继续,但请保留其他更改;它们确实使您的原始答案更好。
猜你喜欢
  • 2021-09-01
  • 2011-04-28
  • 2014-11-05
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
相关资源
最近更新 更多