Static class methods

1

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.