У меня возникли проблемы с использованием методов, как Contains
, Remove
или IndexOf
из TObjectList<T>
класса, , когда T является пользовательский тип, как TSocket
в следующем примере кода.Как использовать такие методы, как Contains, Удалить или IndexOf из TObjectList <T>
Я начал реализацию пользовательского типа 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
возвращает ложное, но должно быть правдой, IndexOf
возвращается -1, но должно быть 0 и Remove
не удаляет объект, но ее следует удалить , Я ожидал, что эти методы будут использовать метод Equals
TSocket
, которого они не сделали. Прочитав документацию, я узнал, что конструктор TObjectList
можно вызвать с использованием IComparer. Поэтому я использовал TEqualityComparer<TSocket>
, чтобы использовать мой метод Equals
. К сожалению, конструктор TObjectList
не поддерживает интерфейс IEqualityComparer
, но вместо этого использует интерфейс IComparer
.
Вопрос: Как использовать такие методы, как Contains
, Remove
или IndexOf
из TObjectList<T>
при использовании пользовательских типов в Delphi? В других языках программирования (например, Java или C#) Equals
используется для сравнения объектов в типах списков. Какой механизм использует Delphi для сравнения объектов?
Обновление Благодарим вас за всестороннюю обратную связь. Я обновил свой вопрос и код соответствующим образом. Я подробно остановился на своих ожиданиях при запуске кода и добавлении дополнительного кода, чтобы сделать мои намерения более ясными. @DavidHeffernan: Реализация действительно была неправильной. Я добавил наследование в TInterfacedObject, чтобы узнать больше о подсчете ссылок. Я удалил TInterfacedObject из кода.
Большая проблема заключается в том, что вы смешиваете эталонные подсчитывали интерфейсы и объекты. Вы должны это прекратить. Всякая часть кода здесь плохо ошибочна. 'Contains',' Remove', 'IndexOf' отлично работают с вашим типом, но вы используете неправильный тип, поэтому вам нужно будет начать заново. –
Извините, если мое качество кода не хорошо, что я все еще пытаюсь выучить язык – MUG4N
Дело в том, что мы можем ответить на этот вопрос, но это не поможет. Проблема глубже. Вы решили использовать ссылки с подсчитанными интерфейсами и должны придерживаться этого. –