![]() |
Anonyme Methoden, Wann,warum, Vorteile
Hallo zusammen,
gesehen habe ich es schon öfters, hier auch wieder: ![]() Ich wollte mal fragen, warum macht man sowas eigentlich bzw. wann und was ist der Vorteil? Warum nicht einfach die Procedure oder Funktion wie gewohnt im privat oder public Teil deklarieren und aufrufen wie gewohnt? Wenn ich diese Procedure/Funktion vielleicht noch an mehreren Stelle benötige, dann macht man sowas doch erst Recht nicht oder? Vielleicht könnt ihr mir hierzu ja mal eure Meinung/Erfahrungen mitteilen. Grüße |
AW: Anonyme Methoden, Wann,warum, Vorteile
Na ja, manchmal ist die kleine Methode so unwichtig, das man sie nicht benennen muss. Es bringt dann nicht notwendigerweise einen Mehrwert, sie 'extra' zu deklarieren.
Bezüglich einer Mehrfachverwendung hast Du natürlich Recht, aber auch hier ist -wegen der extremen Kürze (1 Zeile)- meist auch kein Mehrwert erkennbar, zumal die Lesbarkeit bei expliziter Deklaration nicht wesentlich erhöht wird. Allerdings fördert die Delphi-Syntax nicht gerade die Lesbarkeit. C# ist da mit seinen Lambda-Ausdrücken einfach besser. |
AW: Anonyme Methoden, Wann,warum, Vorteile
Der wahre Wert Anonymer Methoden liegt in ihrer Fähigkeit,
![]() Wird eine Anonyme Methode mehrfach benötigt, kann man auch eine Funktion schreiben, die einfach diese Anonyme Methode zurückgibt. |
AW: Anonyme Methoden, Wann,warum, Vorteile
Man sollte das meistens sowieso nur für kurze Methoden verwenden
und wenn diese Methode auch nur an einer Stelle verwendet wird. IMHO ist der Code so eventuell sogar besser lesbar, da der Code so direkt lesbar ist, als wenn man erst zu der Methode springen muß.
Delphi-Quellcode:
Und grade bei der Synchronisierung ist hier der Vorzeil, daß man lokale Variablen, der übergeordneten Methode, direkt und sogar treadsave an die anonyme Methode übergeben kann, während man bei einer "richtigen" Methode keine Parameter übergeben kann und somit das praktisch mindestens thread-global übergeben muß, inkl. externer Variablen.
...
if Tasks.Count > 0 then begin Tasks[0].RunTask(OverViewF.cmdProgressBackground); Text := Log.GetLastRow; end else Text := 'Nothing to do'; SpringeInHauptthread; begin // man kann gern noch ein logisches begin/end einfügen ... muß man aber nicht if Text <> OverviewF.lblTaskBackground.Caption then Log.AddLog('Setting label to from "' + OverviewF.lblTaskBackground.Caption + '" to "' + Text + '"'); OverviewF.lblTaskBackground.Caption := Text; end; SpringeZurückInDenEigentlichenThread; ... |
AW: Anonyme Methoden, Wann,warum, Vorteile
Ok, also ist es für den "normalen" Anwendungszweck weder von Vorteil, noch von Nachteil.
@Uwe: Kannst du mir mal ein Beispiel zeigen, wo diese Fähigkeit ("lokale Variablen des Scopes mitzunehmen") mal mit ein bisschen Quelltext drum rum anschaulicher wird? Also wo man vielleicht besser dran erkennt, was wirklich der Vorteil davon ist? Das Beispiel auf der von dir verlinkten Seite ist ja eher "spärlich". Ich hätte ja auch einfach eine Methode deklarieren können, der ich direkt x und y mitgebe als Parameter ;-) Grüße |
AW: Anonyme Methoden, Wann,warum, Vorteile
![]() ![]() |
AW: Anonyme Methoden, Wann,warum, Vorteile
Zitat:
|
AW: Anonyme Methoden, Wann,warum, Vorteile
Danke @Stevie. Das muss ich mir erstmal komplett durchlesen ;-)
Grüße |
AW: Anonyme Methoden, Wann,warum, Vorteile
Zitat:
![]() |
AW: Anonyme Methoden, Wann,warum, Vorteile
Zitat:
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz