title: How to use methods like Contains, Remove or IndexOf of TObjectList<T>
body: <p>I am having problems using methods like <code>Contains</code>, <code>Remove</code> or <code>IndexOf</code> of <code>TObjectList&lt;T&gt;</code> class, 
  when T is a custom type like <code>TSocket</code> in the following example code.</p>
  
  <p>I started by implementing a custom <code>TSocket</code> type and tried to use it in a list of type <code>TObjectList&lt;TSocket&gt;</code> like this:</p>
  
  <pre><code>list := nil;
  socket := nil;
  try
    list := TObjectList&lt;TSocket&gt;.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();
  </code></pre>
  
  <p>I expected that <code>Contains</code>, <code>IndexOf</code> and <code>Remove</code> make use of the <code>Equals</code> procedure of <code>TMyObject</code> and overwriten implementation of this procedure. Therefore I added the following implemenation of <code>Equals</code> to my TSocket class:</p>
  
  <pre><code>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;
  </code></pre>
  
  <p>Using this code <code>Contains</code> returns false but should be true, <code>IndexOf</code> returns -1 but should be 0 and <code>Remove</code> does not remove the object but should remove it. I expected these methods would use the <code>Equals</code> method of <code>TSocket</code> which they didn't. After reading the documentation I found out that the constructor of <code>TObjectList</code> can be called with an implemenantion of IComparer. Therefore I implementated an <code>TEqualityComparer&lt;TSocket&gt;</code> in order to use my <code>Equals</code> method.
  Unfortunately the constructor of <code>TObjectList</code> does not support the <code>IEqualityComparer</code> interface but instead use the <code>IComparer</code> interface.</p>
  
  <p><strong>Question:</strong>
  How do I use methods like <code>Contains</code>, <code>Remove</code> or <code>IndexOf</code> of <code>TObjectList&lt;T&gt;</code> when using custom types in Delphi? 
  In other programming languages (like Java or C#) <code>Equals</code> is used to compare objects in list types. What mechanism does Delphi use to compare objects? </p>
  
  <p><strong>Update</strong>
  Thank you for the comprehensive feedback. I have updated my question and the code appropriately. I elaborated on what my expectations were when running the code and added further code to make my intentions clearer.
  @DavidHeffernan: The implementation was indeed wrong. I added inheritance to TInterfacedObject in order to learn more about reference counting. I removed TInterfacedObject from the code.</p>