Delphi 2009中的通用TList<>在IndexOf操作时崩溃

3

我看到很多关于Delphi 2009泛型的错误提及,但从未想过如此基础的问题会在Update 3中失败。如果列表包含1个或多个项目,则调用泛型TList或TObjectList上的IndexOf将导致访问冲突:

type
  TTest = class( TObject );

procedure DoTest;
var
  list : TObjectList< TTest >;
  t : TTest;
begin
  list := TObjectList< TTest >.Create;
  try
    t := TTest.Create;
    list.IndexOf( t ); // No items in list, correct result -1
    list.Add( t );
    list.IndexOf( t ); // Access violation here
  finally
    list.Free;
  end;
end;

异常信息为"EAccessViolation: Access violation at address 0048974C in module 'testbed.exe'. Read of address 00000000"

使用debug DCUs编译会导致泛型集合文件generics.collections.pas中FComparer成员未被赋值的问题:

function TList<T>.IndexOf(const Value: T): Integer;
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
    if FComparer.Compare(FItems[i], Value) = 0 then
      Exit(i);
  Result := -1;
end;

当然,这使得通用的TList几乎完全无用。由于更新3似乎没有修复这个错误,除了升级到XE,我还有其他选择吗?
2个回答

8

谢谢,Roddy!针对问题立即给出解决方案+1。 - Marek Jedliński

6

这是 TObjectList<T> 的默认构造函数中的一个漏洞,我认为它在更新3中已经修复。如果你仍然看到它,请使用其他构造函数或者直接升级到 D2010 或 XE 版本,因为它们肯定已经修复了。(而且如果你想使用泛型,确实应该离开 D2009)。


2
+1 表示“如果你想使用泛型,那么你真的应该放弃 D2009”。我仍然在使用 D2009,并且在尝试使用泛型时遇到了很多麻烦。有太多本应该工作但实际上不起作用的东西。 - lkessler
3
我知道,我知道 :) 但XE升级的价格对于一个业余爱好者来说并不是小数目。我经常使用TObjectList,只是希望泛型可以让我避免不断进行类型转换。我真的没想到问题会这么早就出现。 - Marek Jedliński

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接