2010-11-01 77 views
5

Delphi 1中的16位(是它的老,但它工作得很好)的TStringList - 古怪的行为

一些示例代码:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    SL: TStringList; 
begin 

    SL := TStringList.Create; 
    SL.Sorted := True; 
    SL.Duplicates := dupIgnore; 

    SL.AddObject('A', TObject(100)); 
    SL.AddObject('A', TObject(999)); 
    ShowMessage(IntToStr(LongInt(SL.Objects[0]))); {A} 

    SL.Free; 

end; 

我使用的对象字段存储longints(一劈,是的,但它完成了工作)。无论如何,在上面的A行我希望ShowMessage显示100,而不是显示999(即使dupIgnore设置)。我在这里错过了什么吗?或者它应该以这种方式工作(我希望stringlist忽略999)?

回答

6

刚刚在德尔福2009年测试 - 它显示100(根据德尔福2009年关于重复和dupIgnore文档它应该显示100)。

可能是Delphi 1的一个bug。


更新

@Sertac Akyuz:是的,这似乎是真实的。 Google shows老德尔福版本有以下实现的TStringList.Add和TStringList.AddObject方法:

function TStringList.Add(const S: string): integer; 
begin 
    if not Sorted then 
    Result := FCount 
    else 
    if Find(S, Result) then 
     case Duplicates of 
     dupIgnore: Exit; 
     dupError: Error(SDuplicateString, 0); 
     end; 
    InsertItem(Result, S); 
end; 

function TStrings.AddObject(const S: string; AObject: TObject): Integer; 
begin 
    Result := Add(S); 
    PutObject(Result, AObject); 
end; 

目前(2009年德尔福)的实现是:

function TStringList.Add(const S: string): Integer; 
begin 
    Result := AddObject(S, nil); 
end; 

function TStringList.AddObject(const S: string; AObject: TObject): Integer; 
begin 
    if not Sorted then 
    Result := FCount 
    else 
    if Find(S, Result) then 
     case Duplicates of 
     dupIgnore: Exit; 
     dupError: Error(@SDuplicateString, 0); 
     end; 
    InsertItem(Result, S, AObject); 
end; 

看到区别。旧的实现可能被视为一个错误(内存泄漏等)或一个未公开的允许的行为。无论如何,目前的实施都没有问题。

+0

[Delphi XE文档](http://docwiki.embarcadero.com/VCL/en/Classes.TStringList.AddObject)没有提到它。它只是说重复*字符串*被忽略。它没有说明绑定到重复字符串的对象会发生什么。 – 2010-11-01 17:15:49

+0

@Rob Kennedy - dupIgnore阻止尝试添加重复的字符串(带或不带对象)到排序列表。返回的索引在这种情况下无关紧要 - 字符串不会添加到列表中。 – kludg 2010-11-01 17:35:19

+0

罗布不是在谈论这个字符串 - 它肯定不会被添加。他谈论了绑在弦乐器上的*物体*。文档没有说明对象发生了什么。在早期版本的Delphi中,虽然不添加重复字符串,但绑定到它的对象会替换先前的对象。它应该被认为是一个设计选择,而不是一个bug,可能是一个错误,因为他们改变了它(我见过一个投诉日期为2004年,所以行为可能在D7之后改变)。 – 2010-11-01 23:22:01

3

你不会错过任何东西。这正是发生的情况。

AddObject首先调用Add,它返回列表中新(或现有)元素的索引。然后它调用PutObject在该索引处分配对象值。在文档中未指定相对于Duplicates属性的行为。