Почему метод Delphi TStringList.InsertObject () выбрасывает исключение, если список отсортирован? - PullRequest
6 голосов
/ 24 мая 2011

В Delphi 6, если вы пытаетесь вставить объект в TStringList, который отсортирован (Sorted = true), создается исключение, предупреждающее вас, что InsertObject () не разрешен в отсортированном списке. Я мог бы понять это, если бы вызов InsertObject () обязательно означал разрушение отсортированного порядка в списке. Но учитывая, что метод TStringList.Find ():

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

возвращает индекс, точно указывающий, каким должен быть индекс вставки для данной строки, если он был добавлен в список, и вызов функции InsertObject () с этим индексом должен оставить отсортированный список в порядке сортировки после операции. Я изучил источник Delphi для TStringList, и, похоже, это подтверждает мое утверждение.

На данный момент я просто создаю новый подкласс для TStringList, который переопределяет InsertObject () и не выдает исключение, если InsertObject () вызывается в отсортированном списке, но я хочу убедиться, что некоторые скрытые опасность, которую я просто не вижу.

- Рошлер

Ответы [ 5 ]

7 голосов
/ 24 мая 2011

Вы должны просто позвонить AddObject вместо отсортированного списка.

Если бы InsertObject проверил «правильный» индекс в отсортированных списках, то у вас возник бы кошмар тестирования: при некоторых обстоятельствах ваш код мог бы работать, но внезапно начал бы выдавать исключения, если входные данные изменились. Или, если InsertObject игнорирует параметр Index, его поведение будет крайне неинтуитивным.

Гораздо лучше для InsertObject всегда выдавать, если список отсортирован.

3 голосов
/ 24 мая 2011

Мне кажется, что сообщение об ошибке очень ясно: не разрешается вызывать Insert или InsertObject в отсортированном списке TStringlist. Когда sorted равно true, список строк будет автоматически обрабатывать позицию новой записи, чтобы сохранить список отсортированным. Предполагая, что вставка разрешена, как может список строк знать, что данный индекс не нарушает сортировку? Нужно было бы найти правильный индекс, сравнить его с данным и тогда? Либо используйте найденный, либо бросьте исключение. Таким образом, разрешены только Add или AddObject.

2 голосов
/ 24 мая 2011

Чтобы избежать дублирования двоичного поиска, выполняемого 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);
 
1 голос
/ 24 мая 2011

Не нужно проверять Delphi6, но то же самое в Delphi XE.Если список отсортирован, вы должны использовать вместо него AddObject.Не имеет смысла вставлять объект в определенную позицию, когда список сортирует элементы для вас.

0 голосов
/ 24 мая 2011

Вместо этого используйте TStringList.Add. Он автоматически проверит наличие дубликатов и вставит строку в нужное место

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...