如果你想使用方法的指针作为参数,你需要type
方法function of object
这样的方法 good :
type TAcceptor = function(filename:string):boolean of object;
function acceptor(filename:string):boolean;
begin
result := filename <> '';
end;
如果您想使用子方法的指针怎么办?它不起作用:
procedure TForm1.Button1Click(Sender:TObject);
function acceptor(filename:string):boolean of object;
begin
result := filename <> '';
end;
begin
end;
错误发生:; expected but OF found
!
问题:是否有子功能指针?我可以施展吗?
答案 0 :(得分:7)
我不明白这是怎么回事。
http://docwiki.embarcadero.com/RADStudio/XE6/en/Procedural_Types
如果您查看method pointers部分,则明确说明无法使用嵌套过程和函数:
&#34;嵌套程序和函数(在其他程序中声明的例程) 例程)不能用作程序值,也不能预定义 程序和功能。&#34;
您可以使用匿名方法解决它。类似的东西:
procedure TForm1.Button1Click(Sender:TObject);
begin
DoSomethingWithAcceptor(function(FileName: string): Boolean
begin
Result := FileName <> '';
end);
end;
答案 1 :(得分:1)
我知道以下内容并非普遍适用,但它适用于所有已知的Delphi版本的Delphi。只要你意识到这一点,并在新版本中检查它的功能,它就是一个可行的黑客,IMO。
在较旧的代码中,我用这个来做一些&#34;穷人的匿名方法&#34;:
type
TLocal = packed record
Code: Pointer; // local (nested) function
Frame: Pointer; // outer stack frame for local function
end;
为了在方法中填充这样的局部,我编写了函数Local:
function Local(LocalFunction: Pointer): TLocal;
asm
MOV [EDX].TLocal.Frame,EBP
MOV [EDX].TLocal.Code,EAX
end;
在我的单元(某种通用集合)中,我写了一个函数来调用它们,传递一个参数(类型为TGeneric,在这种情况下,这里不重要,你也可以传递指针或其他一些)
// Calls local function using local closure provided, passing
// T as parameter to the local.
function CallLocal(T: TGeneric; const Local: TLocal): TGeneric;
asm
PUSH [EDX].TLocal.Frame
CALL [EDX].TLocal.Code
ADD ESP,4
end;
它的使用方式如下:
function TStdCollection.AsArray: TGenericArray;
var
I: Integer;
A: TGenericArray;
procedure ToArray(E: TGeneric);
begin
Result[I] := E.Traits.Copy(E);
Inc(I);
end;
begin
SetLength(A, Count);
I := 0;
ForEach(Local(@ToArray));
Assert(I = Count);
Result := A;
end;
嵌套函数中的代码生成元素的副本并将其存储在数组中。然后主程序将嵌套函数ToArray(及其堆栈框架)作为参数传递给ForEach,这是以这种方式实现的:
function TStdCollection.ForEach(Operation: TLocal): ICollection;
var
Enum: IEnumerator;
Elem: TGeneric;
begin
Enum := GetEnumerator;
Elem := Enum.First;
while Elem <> nil do
begin
CallLocal(Elem, Operation);
Elem := Enum.Next;
end;
Result := Self;
end;
这些示例显示了如何使用Locals。我希望这或多或少能回答你的问题。
请注意,此代码是在Delphi 6时间帧中编写的。我知道现在有更好的选择,比如泛型和匿名方法。但如果需要与Delphi 7的兼容性,以上可能是一个解决方案。