program Project55;
{$APPTYPE CONSOLE}
uses
System.Generics.Defaults;
type
TestRec<T> = record
Compare: TComparison<T>;
CompareI: IComparer<T>;
end;
var
TRI: TestRec<Integer>;
begin
TRI.CompareI:= TComparer<Integer>.Default;
TRI.Compare:= TRI.CompareI.Compare; //E2035 Not enough actual parameters
TRI.Compare:= @TRI.CompareI.Compare; //E2035 Not enough actual parameters
end.
我知道我可以将函数体指定为匿名函数,但为什么我不能指定现有函数?
当然以下作品,但这只是愚蠢的:
TRI.Compare:= function(const L,R: integer): Integer
begin
Result:= TRI.CompareI.Compare(L,R);
end;
PS。我正在使用Delphi XE7,但我怀疑这个版本很重要。
答案 0 :(得分:4)
知道fatal error: unexpectedly found nil while unwrapping an Optional value on (item.view as! AllCurrencyList).allccytext.stringValue = "foo"
只是一个与IBoutlet
具有相同签名的方法的接口,并且匿名方法只是一种方法的接口,您可以执行以下操作。
NSMenu
我在Spring4D中使用这个技巧,以避免在IComparer<T>
周围创建一个包装器对象,因为它们是二进制兼容的。{/ p>
答案 1 :(得分:3)
您尝试执行此分配失败,因为无法将接口方法分配给方法引用变量。语言根本不允许这样做。类型不是分配兼容的。有效的赋值源是匿名方法,类方法(实例或类)和单元范围过程。
其他答案中可以看到的技巧都取决于对实施细节的深入了解。这意味着它们可能会发生变化。但就语言而言,不允许你尝试的是什么。
答案 2 :(得分:1)
匿名方法不完全是方法指针。它们被实现为具有单个方法“Invoke”的接口。
可以从匿名方法中提取方法指针,但据我所知,它依赖于匿名方法的当前实现细节,并且可能会受到未来版本delphi的更改。换句话说,我会反对它。这是从巴里凯利的帖子here逐字逐句采取的。 (这比我在这里更彻底地涵盖了这个话题)
procedure MethRefToMethPtr(const MethRef; var MethPtr);
type
TVtable = array[0..3] of Pointer;
PVtable = ^TVtable;
PPVtable = ^PVtable;
begin
// 3 is offset of Invoke, after QI, AddRef, Release
TMethod(MethPtr).Code := PPVtable(MethRef)^^[3];
TMethod(MethPtr).Data := Pointer(MethRef);
end;
根据您的示例,我建议将其作为替代
type
TestRec<T> = record
CompareI: IComparer<T>;
function Compare(const L, R : T) : Integer;
end;
[...]
function TestRec<T>.Compare(const L, R : T) : Integer;
begin
Result := CompareI.Compare(L,R);
end;
但是,它可能/可能不适用于您目前的情况。