title: How to compare TFunc/TProc containing function/procedure of object?
body: <p>We use a <code>TList&lt;TFunc&lt;Boolean&gt;&gt;</code> with some <code>function ... of object</code>s in it and now want to <code>Remove()</code> some of the entries again. But it doesn't work because obviously you simply <strong>can not</strong> compare these <code>reference to ...</code> thingies reliably.</p>
  
  <p>Here's some test code:</p>
  
  <pre><code>program Project1;
  
  {$APPTYPE CONSOLE}
  
  uses
    Generics.Defaults,
    SysUtils;
  
  type
    TFoo = class
    strict private
      FValue: Boolean;
    public
      constructor Create();
      function Bar(): Boolean;
    end;
  
  { TFoo }
  
  function TFoo.Bar: Boolean;
  begin
    Result := FValue;
  end;
  
  constructor TFoo.Create;
  begin
    inherited;
  
    FValue := Boolean(Random(1));
  end;
  
  function IsEqual(i1, i2: TFunc&lt;Boolean&gt;): Boolean;
  begin
    Result := TEqualityComparer&lt;TFunc&lt;Boolean&gt;&gt;.Default().Equals(i1, i2);
  end;
  
  var
    s: string;
    foo: TFoo;
    Fkt1, Fkt2: TFunc&lt;Boolean&gt;;
  
  begin
    try
      Foo := TFoo.Create();
  
      WriteLn(IsEqual(Foo.Bar, Foo.Bar));             // FALSE (1)
      WriteLn(IsEqual(Foo.Bar, TFoo.Create().Bar));   // FALSE (2)
  
      Fkt1 := function(): Boolean begin Result := False; end;
      Fkt2 := Fkt1;
      WriteLn(IsEqual(Fkt1, Fkt2));                   // TRUE  (3)
  
      Fkt2 := function(): Boolean begin Result := False; end;
      WriteLn(IsEqual(Fkt1, Fkt2));                   // FALSE (4)
  
      Fkt2 := function(): Boolean begin Result := True; end;
      WriteLn(IsEqual(Fkt1, Fkt2));                   // FALSE (5)
  
      FreeAndNil(Foo);
    except
      on E:Exception do
        Writeln(E.Classname, ': ', E.Message);
    end;
    Readln(s);
  end.
  </code></pre>
  
  <p>We tried virtually <em>everything</em>, = operator, comparing pointers, etc..</p>
  
  <p>We even tried some really nasty things like repeatedly casting to <code>PPointer</code> and dereferencing until we get equal values, but that of course didn't yield satisfying results either =).</p>
  
  <ul>
  <li>Case (2), (4) and (5) are OK, as there are in fact distinct functions.</li>
  <li>Case (3) is trivial and OK, too.</li>
  <li>Case (1) is what we want to detect, and this is what we can't get to work.</li>
  </ul>
  
  <p>I fear, Delphi stealthily creates two distinct anonymous functions that forward the call to <code>Foo.Bar</code>. In this case we'd be completely powerless, unless we wanted to wade through    a morass of unknown memory... and well, we don't.</p>