有什么区别
TFuncOfIntToString = reference to function(x: Integer): string;@H_404_3@和
TFuncOfIntToString = function(x: Integer): string of object;@H_404_3@我使用的对象
解决方法
让我们考虑以下三种类型声明:
TProcedure = procedure; TMethod = procedure of object; TAnonMethod = reference to procedure;@H_404_3@这些都是非常相似的。在这三种类型的每一种的调用实例方面,调用代码是相同的。差异出现在可以分配给这些类型的变量。
程序类型
TProcedure是一个procedural type.你可以分配一个类型TProcedure这种形式的变量:
procedure MyProcedure; begin end;@H_404_3@这是一个非面向对象的过程。您不能将实例或类方法分配给TProcedure变量。但是,您可以将static class method分配给TProcedure变量。
方法指针
TMethod是一个method pointer.这由对象的存在表示。当有一个TMethod类型的变量时,必须指定:
所以你可以分配这些:
procedure TMyClass.MyMethod; begin end; class procedure TMyClass.MyClassMethod; begin end;@H_404_3@过程类型和方法指针之间的巨大区别在于后者包含对代码和数据的引用。方法指针通常被称为双指针过程类型。一个包含方法指针的变量包含对代码和实例/类的引用。
考虑下面的代码:
var instance1,instance2: TMyClass; method1,method2: TMethod; .... method1 := instance1.MyMethod; method2 := instance2.MyMethod;@H_404_3@现在,虽然method1和method2引用同一段代码,但它们与不同的对象实例相关联。所以,如果我们调用
method1(); method2();@H_404_3@instance1.MyMethod(); instance2.MyMethod();@H_404_3@匿名方法
最后我们来到anonymous methods.这些是比过程类型和方法指针更通用的目的。您可以将以下任何一个赋给使用引用语法定义的变量:
>一个简单的非面向对象的过程。
>实例化类的实例方法。
>类方法。
>匿名方法。例如:
var AnonMethod: TAnonMethod; .... AnonMethod := MyProcedure; // item 1 above AnonMethod := instance1.MyMethod; // item 2 AnonMethod := TMyClass.MyClassMethod; // item 3@H_404_3@var AnonMethod: TAnonMethod; .... AnonMethod := procedure begin DoSomething; end;@H_404_3@与过程类型和方法指针相比,匿名方法的最大好处是它们允许使用variable capture.例如,考虑下面的短程序来说明:
{$APPTYPE CONSOLE} program VariableCapture; type TMyFunc = reference to function(X: Integer): Integer; function MakeFunc(Y: Integer): TMyFunc; begin Result := function(X: Integer): Integer begin Result := X*Y; end; end; var func1,func2: TMyFunc; begin func1 := MakeFunc(3); func2 := MakeFunc(-42); Writeln(func1(4)); Writeln(func2(2)); Readln; end.@H_404_3@这有以下输出:
12 -84 @H_404_3@