Implementation von Methodenverkettung (Method-Chaining)

Sie haben so etwas vielleicht schon einmal gesehen: mehrere Methoden einer Klasse werden innerhalb eines einzigen Aufrufs durch Punkt getrennt nacheinander aufgerufen. Das ist zwar Geschmackssache, aber relativ einfach zu implementieren.

The old-fashioned way

Nehmen wir als Basis eine ganz einfach gestrickte Klasse:
type
  TMyClass = class
  public
    procedure SayHello;
    procedure SayGoodBye;
  end;
  
procedure TMyClass.SayGoodBye;
begin
  ShowMessage('Tschüss, ich mach mich dünne');
end;

procedure TMyClass.SayHello;
begin
  ShowMessage('Hallo Welt');
end;
Benutzt wird das dann wie gewohnt:
procedure TForm1.Button1Click(Sender: TObject);
var
  MyClass: TMyClass;
begin
  MyClass := TMyClass.Create;
  try
    MyClass.SayHello;
    MyClass.SayGoodBye;
  finally
    MyClass.Free;
  end;
end;

Implementation von Method-Chaining

Der Trick ist so simpel wie genial: machen Sie aus allen Prozeduren Funktionen, die eine Instanz der Klasse zurückgeben. Im implementation-Abschnitt geben Sie dann als Result einfach die eigene Instanz zurück.
type
  TMyClass = class
  public
    function SayHello: TMyClass;
    function SayGoodBye: TMyClass;
  end;

function TMyClass.SayGoodBye: TMyClass;
begin
  ShowMessage('Tschüss, ich mach mich dünne');
  Result := self;
end;

function TMyClass.SayHello: TMyClass;
begin
  ShowMessage('Hallo Welt');
  Result := self;
end;
Nun können Sie den Aufruf wie oben gezeigt gestalten oder eben auch kürzer:
procedure TForm1.Button1Click(Sender: TObject);
begin
  TMyClass.Create.SayHello.SayGoodBye.Free;
end;
Wie gesagt: das ist Geschmackssache, aber immerhin möglich. Übrigens sollten Sie auch beim Method-Chaining nicht auf try-finally-Blöcke verzichten, da Sie sich sonst u.U. Speicherlecks einfangen könnten. Wenn also beim letzten Beispielcode in der SayHello-Methode eine Exception auftreten sollte, wird das SayGoodBye und vor allem das Free nicht mehr ausgeführt.