Tlist genérico <> em Delphi 2009 Crash no indexof
-
26-09-2019 - |
Pergunta
Eu já vi muitas menções de bugs em Delphi 2009 genéricos, mas nunca esperava que algo tão básico falhar na Atualização 3, nada menos. Chamar o índiceof em um tlist genérico ou tabjectlist causa uma violação de acesso se a lista contiver 1 ou mais itens:
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;
A exceção é "EaccessViolation: Acesso Violation no endereço 0048974c no módulo 'testbed.exe'. Leia do endereço 00000000"
Compilar com a depuração DCUS leva a um problema em genéricos.collections.pas - o membro do FComparer não está atribuído:
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;
É claro que isso torna o Tlist genérico quase completamente inútil. Como a atualização 3 não parece ter corrigido esse bug, tenho um recurso além de atualizar para o XE?
Solução
Dê uma olhada nesta pergunta. Por que tlist.remove () está produzindo um erro de eaccessriolation?
Em particular, tente criar seu TLIST como este
TList<TTest>.Create(TComparer<TTest>.Default);
Outras dicas
Este é um bug no construtor padrão de TObjectList<T>
, e eu pensei que estava corrigido na atualização 3. Se você ainda está vendo, use um construtor diferente ou apenas atualize para D2010 ou XE, onde é definitivamente corrigido. (E você realmente vai querer sair do D2009 se quiser trabalhar com genéricos de qualquer maneira.)