为什么TList.Remove()产生EAccessViolation错误? [英] Why is TList.Remove() producing an EAccessViolation error?
本文介绍了为什么TList.Remove()产生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屋!
查看全文