Why did the Delphi TStringList.InsertObject () method throw 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 raised warning that InsertObject () is not allowed in the sorted list. I could understand this if calling the InsertObject () function necessarily meant destroying the ordered order of the list. But considering that the TStringList.Find () method:

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

returns an index indicating exactly what the insert index should be for the given row, if it was added to the list, calling the InsertObject () method with this index should leave the sorted list in sorted order after the operation. I studied the Delphi source for the TStringList and seems to have confirmed my claim.

For now, I am just creating a new subclass for TStringList that overrides InsertObject () and does not throw an exception if InsertObject () is called in a sorted list, but I want to make sure that there are no hidden dangers that I just don’t see.

- roschler

+6
source share
5 answers

You should just call AddObject instead in a sorted list.

If InsertObject checked for the β€œcorrect” index in sorted lists, then you will have a nightmare for testing: in some cases, your code will work, but will suddenly throw exceptions if the input has changed. Or, if InsertObject ignores the Index parameter, then its behavior will be wildly unintuitive.

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

+7
source

The error message seems very clear to me: it is not allowed to call Insert or InsertObject in a sorted TStringlist. When sorted correctly, the string list automatically processes the position of the new record to preserve the sorting of the list. Suppose insertion was allowed, how could a list of rows know that a given index does not violate sorting? He would have to find the correct index, compare it with the data, and then? Either use the one found, or throw an exception. Thus, only Add or AddObject is allowed.

+3
source

To avoid duplication of the binary search performed using 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); 
+2
source

No need to check Delphi6, but in Delphi XE it is the same. If the list is sorted, you should use AddObject. It really doesn't make sense to insert an object at a specific position when the list sorts the items for you.

+1
source

Use TStringList.Add instead. It automatically checks for duplicates and inserts the row in the right place.

0
source

Source: https://habr.com/ru/post/888909/


All Articles