6

Delphi 6 では、ソートされた (Sorted = true) TStringList にオブジェクトを挿入しようとすると、例外がスローされ、InsertObject() はソートされたリストでは許可されないという警告が表示されます。InsertObject() を呼び出すことが必然的にリストの並べ替え順序を破棄することを意味する場合、これを理解できました。しかし、TStringList.Find() メソッドを考えると:

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

リストに追加された場合、指定された文字列の挿入インデックスがどうあるべきかを正確に示すインデックスを返します。そのインデックスで InsertObject() を呼び出すと、操作後もソートされたリストがソートされたままになります。TStringList の Delphi ソースを調べたところ、私の主張が裏付けられたようです。

今のところ、InsertObject() をオーバーライドし、並べ替えられたリストで InsertObject() が呼び出された場合に例外をスローしない TStringList の新しいサブクラスを作成していますが、隠れた危険がないことを確認したいと考えています。見てないだけ。

-- ロシュラー

4

5 に答える 5

7

AddObject代わりに、ソートされたリストで呼び出す必要があります。

ソートInsertObjectされたリストの「正しい」インデックスをチェックすると、テストの悪夢に見舞われることになります。状況によっては、コードが機能しているように見えても、入力データが変更されると突然例外をスローし始めることがあります。または、パラメーターをInsertObject無視するIndexと、その動作は非常に直感的ではなくなります。

InsertObjectリストがソートされている場合は、常にスローする方がはるかに優れています。

于 2011-05-24T13:50:19.963 に答える
3

エラー メッセージは非常に明確に思えます。並べ替えられた TStringlist で Insert または InsertObject を呼び出すことは許可されていません。sorted が true の場合、stringlist は新しいエントリの位置を自動的に処理して、リストのソートを維持します。挿入が許可されていると仮定すると、指定されたインデックスが並べ替えを壊さないことを文字列リストはどのように知ることができますか? 正しいインデックスを見つけて、指定されたインデックスと比較する必要がありますか? 見つかったものを使用するか、例外をスローします。したがって、Add または AddObject のみが許可されます。

于 2011-05-24T13:50:47.087 に答える
2

によって実行されるバイナリ検索の重複を避けるために、保護されたメソッド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);
 
于 2011-05-24T15:58:40.170 に答える
1

チェックするDelphi6はありませんが、Delphi XEでも同じです。リストがソートされている場合は、代わりに AddObject を使用する必要があります。リストがアイテムをソートしているときに、特定の位置にオブジェクトを挿入することはあまり意味がありません。

于 2011-05-24T13:50:15.527 に答える
0

代わりに TStringList.Add を使用してください。重複を自動的にチェックし、適切な場所に文字列を挿入します

于 2011-05-24T13:59:46.370 に答える