为什么TList.Remove()产生EAccessViolation错误? [英] Why is TList.Remove() producing an EAccessViolation error?

查看:132
本文介绍了为什么TList.Remove()产生EAccessViolation错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么在执行下面的代码时会引发EAccessViolation?

 使用
Genericics.Collections;
...

var
list:TList< TNotifyEvent> ;;
...

begin
list:= TList< TNotifyEvent> .Create();
try
list.Add(myNotifyEvent);
list.Remove(myNotifyEvent); // EAccessViolation at address ...
finally
FreeAndNil(list);
结束
结束

procedure myNotifyEvent(Sender:TObject);
begin
OutputDebugString('event'); // nebo cokoliv jineho
end;


解决方案

它看起来像一个错误。 b
$ b

如果您使用debug dcu进行编译(通常不要这样做,除非你想松开理智!)你看到对比较器的调用发生错误。一个(可能是可选的)比较函数的第三个值没有被设置并导致访问冲突。



所以可能你不能把方法指针放在通用列表中。 / p>

确定以下作品:

 使用
泛型。默认值

type
TForm4 = class(TForm)
...
private
procedure myNotifyEvent(Sender:TObject);
结束

TComparer< T> = class(TInterfacedObject,IComparer< T>)
public
函数Compare(const Left,Right:T):Integer;
结束

实现

使用
泛型。

var
list:TList< TNotifyEvent> ;;
begin
list:= TList< TNotifyEvent> .Create(TComparer< TNotifyEvent> .Create);
try
list.Add(myNotifyEvent);
list.Remove(myNotifyEvent);
finally
FreeAndNil(list);
结束
结束

procedure TForm4.myNotifyEvent(Sender:TObject);
begin
ShowMessage('event');
结束

{TComparer< T> }

函数TComparer< T> .Compare(const Left,Right:T):Integer;
begin
结果:= 0;
结束

您必须定义自己的比较器,可能会有更多的智能; - )。


Why EAccessViolation is raised when executing the code below?

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;

解决方案

It looks like a bug.

If you compile with debug dcu's (normally don't do that unless you want to loose your sanity!) you see that a call to the comparer went wrong. A (possibly optional) third value of a compare function is not set and causes the access violation.

So possibly you can't put method pointers in a generic list.

Ok the following works:

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;

You have to define your own comparer, with possiby some more intelligence ;-).

这篇关于为什么TList.Remove()产生EAccessViolation错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆