OK, dann hab ich nun erstmal endlich Klarheit, was diese Operatoren wirklich machen.
Delphi-Quellcode:
procedure Test;
var
A, B: TTest;
begin
end;
Normal sind hier im BEGIN und END (wobei der Debugger in der CPU-Ansicht behauptet es wäre im BEGIN) die Standartbehandlungen für Managed-Typen, wie String, DymArrays, Interfaces und Variants.
"einfache" Typen werden hier ja bekanntlich nicht initialisiert.
Achtung, ein Result (Managed-Type) von aufgerufenen Funktionen sind in Wirklichkeit als VAR-Parameter implementiert, mit einer automatischen lokalen Variable.
Drum ist z.B. ein
function Test: string;
initialisiert, aber nicht dort, wo man es denkt, also nicht in der Funktion, sondern beim Aufrufer,
weswegen z.B. Aufrufe in Schleifen sich echt witzig auswirken.
Und das ohne, dass der Compiler hier eine Warnung ausgibt, von wegen "Result sei nicht initialisiert", denn es ist das ja.
Delphi-Quellcode:
function Test: string;
begin
Result := Result + '*';
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
for var i := 1 to 3 do
ShowMessage(Test);
end;
Hier kommt
*
,
**
und
***
raus, anstatt drei Mal
*
.
PS: Boolean-Result werden scheinbar seit einer Weile mit False initialisiert, wohl weil es zu viele Entwickler gab, welche sämtliche Warnungen ignorieren.
Auch wenn ich diese Initialisierung nirgends finde.
[EDIT] Nein, es ist doch Zufall, dass es "meistens" False war.
Weiter siehe
https://www.delphipraxis.net/215251-...ialisiert.html [/EDIT]
Bei einem Record mit den neuen Managed-Operatoren, befindet die sich Standard-Initialisierung im BEGIN des Operators.
Da, wo die Record-Variable deklariert ist, gibt es also nur noch den einen CALL.
Ebenso befindet sich die Standard-Finalisierung im END des Finalize-Operators, anstatt im END bei der Variablen-Deklaration.
Beim Assign-Operator wird garnichts kopiert und man muß ALLES selbst machen, für jedes Feld einzeln.
Dest := Src;
, sowie RecordCopy oder ArrayCopy (mit Länge 1) ergeben
leider Endlosschleifen, da sie den Operator aufrufen.
-> Hier werde ich demnächst einen FeatureRequest erstellen, mit der Bitte innerhalb des Operators so zu tun, als gäbe es den Operator nicht.
War ursprünglich davon ausgegangen, dass der AssignOperator auch im oder vor dem BEGIN das Standardverhalten hat, was ich in meinem Anwendungsfall aber nicht gebrauchen konnte und es somit für mich eigentlich vollkommen OK ist, wobei ein
Dest := Src;
uns dennoch das Leben erleichtern könnte und Fehlern vorbeugen könnte, wenn der Record irgendwann um neue Felder erweitert wird.
Bisher hatte ich in meinen Records zufällig nur managed Typen oder Pointer und Diese mußte ich sowieso manuell kopieren, inkl. manueller Referenzzählung.