想象一下,我有一个这样的课程:
type TFunctionWrapper<T1,T2> = class
private
FFunc : TFunc<T1,T2>;
public
constructor Create(AFunc : TFunc<T1,T2>);
function Apply(AValue : T1) : T2;
end;
实施
constructor TFunctionWrapper<T1,T2>.Create(AFunc : TFunc<T1,T2>);
begin
FFunc := AFunc;
end;
function TFunctionWrapper<T1,T2>.Apply(AValue : T1) : T2;
begin
Result := FFunc(AValue);
end;
如果指定的功能相同,我该如何测试?函数引用不能等同于F1 = F2
,因为它会导致编译器错误:
[dcc32 Error] Project1.dpr(37): E2035 Not enough actual parameters
,
这很有道理。
无论如何,问题仍然存在:如何测试是否将字段中的函数分配给预期的工作,而不仅测试字段和函数是否在同一输入上返回相同的结果? < / p>
答案 0 :(得分:0)
这些是使用reference to
声明的引用方法类型。它们作为接口实现,由编译器自动创建和管理。
因此,您可以通过强制转换为接口并使用接口相等来测试相等性:
IInterface(Pointer(@F1)^) = IInterface(Pointer(@F2)^)
这有点粗糙,感谢Stefan Glienke的回答,告诉我如何:https://stackoverflow.com/a/22645248/505088
但请注意,这可能无法给出您期望的结果。比如这个程序:
{$APPTYPE CONSOLE}
uses
System.SysUtils;
function Foo(Value: Integer): Integer;
begin
Result := Value;
end;
var
F1, F2: TFunc<Integer, Integer>;
begin
F1 := Foo;
F2 := Foo;
Writeln(IInterface(Pointer(@F1)^) = IInterface(Pointer(@F2)^));
Readln;
end.
输出FALSE
。那是因为编译器为F1
和F2
创建了两个不同的匿名方法。理论上,编译器可以检测两个匿名方法在同一个上下文中调用相同的函数,并优化此代码以使用单个匿名方法。但编译器不这样做。