为什么在执行下面的代码时会引发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;
你必须定义自己的比较器,可能有更多的智能;-).