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
利用し、この手順の実装を上書きしました。したがって、次の実装をTSocket クラスに追加しました。Equals
TMyObject
Equals
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 を削除しました。