我们使用一个包含一些对象的函数列表
TList<TFunc<Boolean>>
,现在想要再次删除其中的一些条目。但是它不起作用,因为很明显您无法可靠地比较这些引用对象 reference to ...
。
以下是测试代码: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
的调用。在这种情况下,我们将完全无能为力,除非我们想要穿越未知的内存深渊...而好吧,我们不想。
var F: TFunc<Boolean>; ShowMessage(IntToStr(SizeOf(F)));
- 它在我的 Delphi 2010 中显示为 1!这怎么可能? - Cosmin Prund