8 delphi generics delphi-2009 tlist
为什么在执行下面的代码时会引发EAccessViolation?
uses
Generics.Collections;
...
var
list: TList<TNotifyEvent>;
...
begin
list := TList<TNotifyEvent>.Create();
try
list.Add(myNotifyEvent);
list.Remove(myNotifyEvent); // EAccessViolation at address...
finally
FreeAndNil(list);
end;
end;
procedure myNotifyEvent(Sender: TObject);
begin
OutputDebugString('event'); // nebo cokoliv jineho
end;
Run Code Online (Sandbox Code Playgroud)
它看起来像一个bug.
如果使用debug dcu进行编译(通常不要这样做,除非你想要失去理智!)你会看到对比较器的调用出错了.未设置比较函数的(可能是可选的)第三个值并导致访问冲突.
因此,您可能无法将方法指针放在通用列表中.
好的以下工作:
uses
Generics.Defaults;
type
TForm4 = class(TForm)
...
private
procedure myNotifyEvent(Sender: TObject);
end;
TComparer<T> = class (TInterfacedObject, IComparer<T>)
public
function Compare(const Left, Right: T): Integer;
end;
implementation
uses
Generics.Collections;
var
list: TList<TNotifyEvent>;
begin
list := TList<TNotifyEvent>.Create(TComparer<TNotifyEvent>.Create);
try
list.Add(myNotifyEvent);
list.Remove(myNotifyEvent);
finally
FreeAndNil(list);
end;
end;
procedure TForm4.myNotifyEvent(Sender: TObject);
begin
ShowMessage('event');
end;
{ TComparer<T> }
function TComparer<T>.Compare(const Left, Right: T): Integer;
begin
Result := 0;
end;
Run Code Online (Sandbox Code Playgroud)
你必须定义自己的比较器,可能有更多的智能;-).
小智 0
上面的代码在TForm1中使用...
uses
Generics.Collections;
procedure TForm1.Button1Click(Sender: TObject);
var
list: TList<TNotifyEvent>;
begin
list := TList<TNotifyEvent>.Create();
try
list.Add(myNotifyEvent);
list.Remove(myNotifyEvent); // EAccessViolation at address...
finally
FreeAndNil(list);
end;
end;
procedure TForm1.myNotifyEvent(Sender: TObject);
begin
OutputDebugString('event'); // nebo cokoliv jineho
end;
Run Code Online (Sandbox Code Playgroud)