Как сравнить TFunc / TProc, содержащие функцию / процедуру объекта?

Мы используем TList > с некоторой функцией ... объекта s в нем и теперь снова хочу Remove () некоторые записи. Но это не работает, потому что, очевидно, вы просто не можете сравнить эти ссылки с ...

Вот тестовый код:

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<Boolean>): Boolean;
begin
  Result := TEqualityComparer<TFunc<Boolean>>.Default().Equals(i1, i2);
end;

var
  s: string;
  foo: TFoo;
  Fkt1, Fkt2: TFunc<Boolean>;

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.

Мы испробовали практически все , = оператор, сравнение указателей и т. д.

Мы даже пробовали некоторые действительно неприятные вещи, такие как многократное приведение к PPointer и разыменование до тех пор, пока мы не получим равные значения, но это, конечно же, не дало удовлетворительных результатов ).

  • Случаи (2), (4) и (5) допустимы, так как на самом деле существуют разные функции.
  • Случай (3) тривиален и также допустим.
  • Случай (1) является что мы хотим обнаружить, а это то, что мы не можем заставить работать.

Боюсь, Delphi незаметно создает две отдельные анонимные функции, которые перенаправляют вызов на Foo.Bar . В этом случае мы были бы совершенно бессильны, если бы мы не хотели пробираться через болото неизвестных воспоминаний ... а мы этого не делаем.

11
задан kiw 1 March 2011 в 10:53
поделиться