Consider the following Delphi code:
unit Unit2; interface uses Dialogs; type TNamedObj = class private FObjName: string; public constructor Create(const AName: string); procedure ShowName1; class procedure ShowName2(Obj: TNamedObj); static; end; implementation constructor TNamedObj.Create(const AName: string); begin FObjName:= AName; end; procedure TNamedObj.ShowName1; begin ShowMessage(FObjName); end; class procedure TNamedObj.ShowName2(Obj: TNamedObj); begin ShowMessage(Obj.FObjName); end; end.
At a first glance ShowName2 looks like a useless addition. It does the same thing as ShowName1, and the compiler generates identical code for both.
Static class methods were made type compatible with ordinary procedures (functions). In the above example the static class method implementation of ShowName is type compatible with
type TShowProc = procedure(Obj: TNamedObj);
and that allows you to pass ShowName2 code as an argument:
type TShowProc = procedure(Obj: TNamedObj); procedure TestShowName2(Proc: TShowProc); var Obj: TNamedObj; begin Obj:= TNamedObj.Create('Apple'); Proc(Obj); Obj.Free; end; procedure TForm1.Button1Click(Sender: TObject); begin TestShowName2(TNamedObj.ShowName2); end;
You need some unclean hackish trick to do the same with an object method:
type TShowMeth = procedure of object; procedure TestShowName1(Proc: Pointer); var Obj: TNamedObj; Meth: TMethod; begin Obj:= TNamedObj.Create('Apple'); Meth.Data:= Obj; Meth.Code:= Proc; TShowMeth(Meth); Obj.Free; end; procedure TForm1.Button2Click(Sender: TObject); begin TestShowName1(@TNamedObj.ShowName1); end;
See also the related SO question.