将一个过程或是函数作为其它过程或函数的参数
时间:2010-08-08 来源:入侵
原文:http://delphi.about.com/od/adptips2006/qt/functionasparam.htm
How to Use a Function or a Procedure as a Parameter in another Function
Zarko Gajic,
In Delphi, procedural types (method pointers) allow you to treat procedures and functions as values
that can be assigned to variables or passed to other procedures and functions.
Here's how to call a function (or procedure) as a parameter of another function (or procedure) :
1. Declare the function (or procedure) that will be used as a parameter.
In the example below, this is "TFunctionParameter".
2. Define a function that will accept another function as a parameter.
In the example below this is "DynamicFunction"
type TFunctionParameter = function(const value : integer) : string; ... function One(const value : integer) : string; begin result := IntToStr(value) ; end; function Two(const value : integer) : string; begin result := IntToStr(2 * value) ; end; function DynamicFunction(f : TFunctionParameter) : string; begin result := f(2006) ; end; ... //Example usage: var s : string; begin s := DynamicFunction(One) ; ShowMessage(s) ; //will display "2006" s := DynamicFunction(Two) ; ShowMessage(s) ; // will display "4012" end;
Note:
* Of course, you decide on the signature of the "TFunctionParameter": whether it is a procedure or a function,
how many parameters does it take, etc.
* If "TFunctionParameter" is a method (of an instance object) you need to add the words of object to
the procedural type name, as in:
TFunctionParameter = function(const value : integer) : string of object;
* If you expect "nil" to be specified as the "f" parameter, you should test for this using the Assigned function.
* Fixing the "Incompatible type: 'method pointer and regular procedure'"
===============
在我实际的应该中。
比如我在开始数据库类软件的,通常需要判断一个数据集是否修改,如果修改就要保存,但是通过这个保存方式会是一个 button 的click 方法:
如:
if ClientDataSet1.changecount>0 then 运行那个 button的click。如果要将这个判断作在一个通用的 函数(或过程中)就要将这个 button.click 作为这个 函数(或过程)的一个函数;
方法如下:
type TButtonClick = procedure (Sender: TObject) of object; ..... function TDM.PUBF_CheckClientDataSetState(CDS: TClientDataSet;BtnClick:TButtonClick): Boolean; begin Result :=True ; if (CDS.State in [dsEdit,dsInsert ]) or (CDS.ChangeCount >0) then begin case MsgBox('数据尚未保存,你要保存数据吗?',5) of //MsgBox 函数是简过的函数; IDYes: BtnClick(nil); IDNO : CDS.Cancel; IDCancle : Result := False end; end; end;
调用的方法:
procedure TF_CompanyInfo.FormClose(Sender: TObject; var Action: TCloseAction); begin if DM.PUBF_CheckClientDataSetState(dm.CDS_CompanyInfo,TB_SaveClick) then Action := cafree else Action := caNone; end;