如果列表已排序,为什么 Delphi 的 TStringList.InsertObject() 方法会抛出异常?

发布于 2024-11-09 06:46:57 字数 534 浏览 5 评论 0原文

在 Delphi 6 中,如果您尝试将对象插入已排序的 TStringList (Sorted = true),则会抛出异常,警告您在已排序的列表中不允许使用 InsertObject()。如果调用 InsertObject() 必然意味着破坏列表的排序顺序,我可以理解这一点。但考虑到 TStringList.Find() 方法:

function TStringList.Find(const S: string; var Index: Integer): Boolean;

返回一个索引,准确地告诉您如果将给定字符串添加到列表中,插入索引应该是什么,使用该索引调用 InsertObject() 应该使排序列表仍处于排序状态手术后下单。我已经检查了 TStringList 的 Delphi 源代码,它似乎证实了我的断言。

现在我只是为 TStringList 创建一个新的子类,它重写 InsertObject() 并且如果在排序列表上调用 InsertObject() 则不会抛出异常,但我想确保不存在一些隐藏的危险我只是没看到。

——罗施勒

In Delphi 6 if you try to insert an object into a TStringList that is sorted (Sorted = true) an Exception is thrown warning you that InsertObject() is not allowed on a sorted list. I could understand this if calling InsertObject() necessarily meant destroying the Sorted order of the list. But given that the TStringList.Find() method:

function TStringList.Find(const S: string; var Index: Integer): Boolean;

returns an index telling you exactly what the insertion index should be for a given string if it were added to the list, calling InsertObject() with that index should leave the sorted list still in sorted order after the operation. I've examined the Delphi source for TStringList and it seems to bear out my assertion.

For now I'm just creating a new sub-class for TStringList that overrides InsertObject() and does not throw an Exception if InsertObject() is called on sorted list, but I want to make sure there isn't some hidden danger that I'm just not seeing.

-- roschler

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我的黑色迷你裙 2024-11-16 06:46:57

您应该只在排序列表上调用 AddObject

如果 InsertObject 检查排序列表上的“正确”索引,那么您将遇到一个测试噩梦:在某些情况下,您的代码似乎可以工作,但如果输入数据会突然开始抛出异常改变了。或者,如果 InsertObject 忽略了 Index 参数,那么它的行为将非常不直观。

如果列表已排序,InsertObject 最好总是抛出异常。

You should just call AddObject instead on a sorted list.

If InsertObject checked for the 'correct' index on sorted lists, then you'd have a testing nightmare: Under some circumstances, your code would appear to work, but would suddenly start throwing exceptions if the input data changed. Or, if InsertObject ignored the Index parameter, then its behaviour would be wildly non-intuitive.

It's much better for InsertObject to always throw if the list is sorted.

星光不落少年眉 2024-11-16 06:46:57

错误消息对我来说似乎非常清楚:不允许在已排序的 TStringlist 上调用 Insert 或 InsertObject。当sorted为true时,字符串列表将自动处理新条目的位置以保持列表排序。假设允许插入,字符串列表如何知道给定的索引不会破坏排序?它必须找到正确的索引,将其与给定的索引进行比较,然后呢?要么使用找到的一个,要么抛出异常。因此只允许添加或添加对象。

The error message seems very clear to me: it is not allowed to call Insert or InsertObject on a sorted TStringlist. When sorted is true, the stringlist will automatically handle the position of the new entry to keep the list sorted. Assuming Insert were allowed, how could the stringlist know that the given index doesn't break the sorting? It would have to find the correct index, compare it with the given one and then? Either use the found one or throw an exception. Thus only Add or AddObject is allowed.

蓝眼睛不忧郁 2024-11-16 06:46:57

为了避免重复由 Find 执行的二分搜索,您可以使用受保护的 InsertItem 方法:

type
  THackSL = class(TStringList);

...

var
  i: Integer;
  s: string;
begin
  ...
  if not MyStringList.Find(s, i) then
    THackSL(MyStringList).InsertItem(i, s, nil);
 

To avoid to duplicate the binary search carried out by Find, you can use the protected InsertItem method:

type
  THackSL = class(TStringList);

...

var
  i: Integer;
  s: string;
begin
  ...
  if not MyStringList.Find(s, i) then
    THackSL(MyStringList).InsertItem(i, s, nil);
 
东京女 2024-11-16 06:46:57

没有Delphi6可以检查,但在Delphi XE中是一样的。如果列表已排序,您应该使用 AddObject。当列表为您对项目进行排序时,在特定位置插入对象实际上没有意义。

Don't have Delphi6 to check but it is the same in Delphi XE. If the list is sorted you should use AddObject instead. Does not really make sense to insert an object at a specific position when the list is sorting the items for you.

手心的海 2024-11-16 06:46:57

请改用 TStringList.Add。它会自动检查重复项并将字符串插入到正确的位置

Use TStringList.Add instead. It will automatically check for duplicates and insert the string in the right place

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文