当 T 是以下示例代码中的自定义类型时,我在使用类似 或 类Contains
的方法时遇到Remove
问题IndexOf
。TObjectList<T>
TSocket
我首先实现了一个自定义TSocket
类型,并尝试在这样的类型列表中使用它TObjectList<TSocket>
:
list := nil;
socket := nil;
try
list := TObjectList<TSocket>.Create();
socket := TSocket.Create(TIpAddress.Parse('127.0.0.1'),6857);
// add new socket object with equal values to list
list.Add(TSocket.Create(TIpAddress.Parse('127.0.0.1'),6857));
// should return true but returns false
if list.Contains(socket) then
WriteLn('socket contained in list')
else
WriteLn('socket not contained in list');
// should return number 0 but returns -1
if list.IndexOf(socket) = 0 then
WriteLn('socket contained in list')
else
WriteLn('socket not contained in list');
// should remove item from list but items doesn't get removed
list.Remove(socket);
finally
list.Free();
socket.Free();
我期望Contains
,IndexOf
并Remove
利用该Equals
程序的程序TMyObject
并覆盖该程序的执行。Equals
因此,我在我的 TSocket 类中添加了以下实现:
type
TSocket = class
strict private
_ipAddress: TIpAddress;
_port: integer;
public
constructor Create(ipAddress: TIpAddress; port: integer);
function GetIpAddress: TIpAddress;
function GetPort: integer;
property IpAddress: TIpAddress read GetIpAddress;
property Port: integer read GetPort;
function Equals(other: TObject): boolean; overload; override;
destructor Destroy; override;
end;
implementation
constructor TSocket.Create(ipAddress: TIpAddress; port: integer);
begin
inherited Create();
_ipAddress := ipAddress;
_port := port;
end;
function TSocket.Equals(other: TObject): boolean;
var
otherSocket: TSocket;
begin
if not (other is TSocket) then exit(false);
otherSocket := other as TSocket;
result:= (_ipAddress.Equals(otherSocket.IpAddress)) and (_port = otherSocket.Port)
end;
function TSocket.GetIpAddress: TIpAddress;
begin
result := _ipAddress;
end;
function TSocket.GetPort: integer;
begin
result := _port;
end;
destructor TSocket.Destroy;
begin
_ipAddress.Free();
inherited Destroy();
end;
使用此代码Contains
返回 false 但应为 true,IndexOf
返回 -1 但应为 0 并且Remove
不删除对象但应删除它。我希望这些方法会使用他们没有使用的Equals
方法。TSocket
阅读文档后,我发现TObjectList
可以使用 IComparer 的实现来调用构造函数。因此我实现了一个TEqualityComparer<TSocket>
为了使用我的Equals
方法。不幸的是,构造函数TObjectList
不支持IEqualityComparer
接口,而是使用IComparer
接口。
问题:在 Delphi 中使用自定义类型时
如何使用Contains
,Remove
或IndexOf
of 之类的方法?TObjectList<T>
在其他编程语言(如 Java 或 C#)Equals
中,用于比较列表类型中的对象。Delphi 使用什么机制来比较对象?
更新 感谢您的全面反馈。我已经适当地更新了我的问题和代码。我详细说明了我在运行代码时的期望,并添加了更多代码以使我的意图更加清晰。@DavidHeffernan:实施确实是错误的。我向 TInterfacedObject 添加了继承,以了解有关引用计数的更多信息。我从代码中删除了 TInterfacedObject。