Einzelnen Beitrag anzeigen

Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#10

AW: Anonyme Methoden, Wann,warum, Vorteile

  Alt 30. Sep 2014, 10:25
Der wahre Wert Anonymer Methoden liegt in ihrer Fähigkeit, lokale Variablen des Scopes mitzunehmen, in denen sie (die Anonyme Methode) deklariert werden.
Ist das bei einer Prozedur innerhalb einer Methode anders?
Ja! Nicht, was die Variablen betrifft, aber bei dem Zeitpunkt der Ausführung. Eine lokale Prozedur L innerhalb einer Methode M kann nur innerhalb dieser Methode M aufgerufen werden. Für alles außerhalb von M ist sie schlichtweg nicht sichtbar. Die lokalen Variablen von M sind dann, bei entsprechender Anordnung des Quelltexts, innerhalb von L verfügbar. Eine Anonyme Methode A kann aber auch außerhalb des Kontexts von M aufgerufen werden, in dem sie deklariert wurde. Trotzdem kann sie auf die lokalen Variablen von M zugreifen, obwohl M zu diesem Zeitpunkt schon längst beendet wurde.

Gerne verwendete Beispiele sind sicher die Methoden Synchronize und Queue aus TThread. Diesen kann man entweder parameterlose Methoden (procedure of object) oder eben auch parameterlose Anonyme Methoden mitgeben. Bei den simplen Methoden muss man die eigentlich benötigten Parameter in Felder der abgeleiteten Thread-Klasse stecken (Nein, globale Variablen sind da bei Todesstrafe verboten!). Das mag bei Synchronize noch gehen, da dort der Aufruf, wie der Name vermuten lässt, synchron geschieht. Bei Queue ist das aber nicht so. Da bietet sich eine Anonyme Methode an, die auf eine lokale Variable zugreift.

Hier mal ein typischerweise absolut sinnfreies Beispiel:

Delphi-Quellcode:
program Project36;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Generics.Collections,
  System.Classes;

type
  TMyThread = class(TThread)
  public
    class procedure ExecuteThread;
  end;

  TMyThread1 = class(TMyThread)
  protected
    procedure Execute; override;
  end;

  TMyThread2 = class(TMyThread)
  protected
    procedure Execute; override;
    function MakeAnonMeth(Value: Integer): TThreadProcedure;
  end;

class procedure TMyThread.ExecuteThread;
var
  instance: TMyThread;
begin
  instance := Self.Create;
  try
    instance.WaitFor;
  finally
    instance.Free;
  end;
end;

procedure TMyThread1.Execute;
var
  I: Integer;
  aProc: TThreadProcedure;
begin
  aProc := Procedure
    begin
      Writeln(Format('%d Prozent', [I]));
    end;
  for I := 0 to 100 do begin
    Synchronize(aProc);
  end;
end;

procedure TMyThread2.Execute;
var
  I: Integer;
begin
  for I := 0 to 99 do begin
    Queue(MakeAnonMeth(I));
  end;
  Synchronize(MakeAnonMeth(100));
end;

function TMyThread2.MakeAnonMeth(Value: Integer): TThreadProcedure;
begin
  result := Procedure
    begin
      Writeln(Format('%d Prozent', [Value]));
    end;
end;

begin
  TMyThread1.ExecuteThread;
  TMyThread2.ExecuteThread;
  Readln;
end.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat