为什么在执行下面的代码时会引发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;
解决方法
它看起来像一个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;
你必须定义自己的比较器,可能有更多的智能;-).