开发者

Why does Delphi's TStringList.InsertObject() method thrown an Exception if the list is Sorted?

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 yo开发者_JS百科u 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


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.


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.


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);
 


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜