2011-05-24 22 views
6

Delphi 6'da, bir nesneye (sıralı bir şekilde bir sırala (Sorted = true) bir TStringList içine eklemeye çalışırsanız, özel bir listeye InsertObject() izin verilmediğini bildiren bir özel durum uyarılır. InsertObject() öğesini çağırmak, mutlaka listenin Sıralı düzenini yoketmek anlamına gelirse bunu anlayabilirim. Ama TStringList.Find() yöntemi göz önüne alındığında: Delphi'nin TStringList.InsertObject() yöntemi neden liste sıralanıyorsa bir özel durum oluşturdu?

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

o indeksi InsertObject() çağırarak, listeye eklenen eğer tam olarak ne ekleme endeksi belirli bir dizeye ilişkin olmalıdır anlatan bir dizin döndürür gerektiği İşlemden sonra sıralanan listeyi hala sıralanmış sırayla bırakın. TStringList için Delphi kaynağını inceledim ve iddiamı ortaya koyuyor gibi görünüyor.

Şimdilik yalnızca InsertObject() öğesini geçersiz kılan ve Sıralı Listede InsertObject() çağrılırsa bir Özel Durum atamayan TStringList için yeni bir alt sınıf oluşturuyorum, ancak bazılarının olduğundan emin olmak istiyorum. Göremediğim gizli tehlike.

- roschler

+2

Neden sadece yok 'AddObject''ü çağırıp doğru dizine sihirli bir şekilde eklenecek mi? –

cevap

7

Sıralı bir listede bunun yerine AddObject numaralı telefonu arayın.

InsertObject, sıralanmış listelerin 'doğru' dizinini işaretlediyse, o zaman bir test kabusuna sahip olursunuz: Bazı durumlarda kodunuz çalışmaya başlardı, ancak giriş verileri değiştiğinde aniden istisnalar atar. Ya da, InsertObject, Index parametresini yoksayarsa, davranışı çılgınca sezgisel olmaz.

Liste sıralanırsa, her zaman InsertObject için atmak daha iyidir.

+0

Başka bir nedenden dolayı indeksi de isterseniz: 'AddObject' dizini döndürür. Ve nesneyi hiç eklememeye karar vermek için, kendiniz tarafından bulunan indekse göre, bkz. Kod Sertaç Akyüz. – NGLN

1

Delphi6 kontrol etmek zorunda etmeyin ama Delphi XE aynıdır. Liste sıralanırsa, bunun yerine AddObject kullanmalısınız. Liste nesneleri sizin için sıraladığında belirli bir konumda bir nesneyi eklemek gerçekten mantıklı değildir.

3

Hata mesajı bana çok açık görünüyor: Sıralı bir TStringlist'e Insert veya InsertObject öğesini çağırmasına izin verilmiyor. Sıralı olduğunda, liste sıralı tutmak için dize listesi yeni girdinin konumunu otomatik olarak işleyecektir. Eklemeye izin verildiği kabul edildi, söz konusu dizinin verilen dizinin sıralamadan nasıl ayrıldığını bilmesi nasıl mümkün olabilirdi? Doğru indeksi bulmak, verilen ile karşılaştırmak ve sonra? Bulunan birini kullanın ya da bir istisna atın. Bu nedenle sadece Add veya AddObject'e izin verilir.

0

Kullanım TStringList.Add yerine. Otomatik olarak korunan InsertItem yöntemi kullanabilirsiniz,

+0

Duplicates özelliğine bağlı olarak http://docwiki.embarcadero.com/VCL/en/Classes.TStringList.Duplicates –

2

ikili arama Find tarafından yürütülen çoğaltmak önlemek için çiftleri kontrol ve doğru yerde dize ekler:

type 
    THackSL = class(TStringList); 

... 

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

Performans ipucu için teşekkürler. Bilmek güzel. –

+0

@Robert - Rica ederim! Ama bunu bir cevap olarak değil, bir ipucu olarak yayınlamayı planladım. Sorunu yanlış anladım mı? Alt klaslı dize listenizle arama çoğaltmasından kaçınmadınız mı? –

+0

Eh, bir performans ipucu gerçekten değil: questioner zaten 'Find' kullandı.;) – NGLN