"Linke Seite kann nicht zugewiesen werden" für Datensatztypeigenschaften in Delphi
Ich bin neugierig, zu wissen, warum Delphi behandelt record type Eigenschaften, als nur zu Lesen:
TRec = record
A : integer;
B : string;
end;
TForm1 = class(TForm)
private
FRec : TRec;
public
procedure DoSomething(ARec: TRec);
property Rec : TRec read FRec write FRec;
end;
Wenn ich versuche, das zuweisen eines Wertes zu jedem der Mitglieder der Rec-Eigenschaft, ich werde "Linke Seite kann nicht zugeordnet werden" Fehler:
procedure TForm1.DoSomething(ARec: TRec);
begin
Rec.A := ARec.A;
end;
während Sie das gleiche mit der darunter liegenden Feld ist erlaubt:
procedure TForm1.DoSomething(ARec: TRec);
begin
FRec.A := ARec.A;
end;
Gibt es eine Erklärung für das Verhalten?
Hinsichtlich
InformationsquelleAutor der Frage vcldeveloper | 2009-03-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Seit "Rec" ist eine Eigenschaft, die der compiler behandelt es ein wenig anders, denn es muss zuerst bewerten Sie das "Lesen" der Immobilie decl. Betrachten Sie diese, was ist semantisch äquivalent zu deinem Beispiel:
Wenn man sich anschaut, wie diese, können Sie sehen, dass die erste Referenz auf "Rec" (vor dem Punkt ('.'), rufen Sie GetRec, die erstellt eine temporäre lokale Kopie von Rec. Diese Provisorien sind by design "nur Lesen." Dies ist, was Sie ausführen in.
Andere Sache, die Sie hier tun können, ist zu brechen, die einzelnen Felder des Datensatzes als Eigenschaften der enthaltenden Klasse:
Dies erlaubt Ihnen die direkte Zuordnung über die Eigenschaft, um das Feld der embedded-Datensatz in der Instanz der Klasse.
InformationsquelleAutor der Antwort Allen Bauer
Ja das ist ein problem. Aber das problem kann behoben werden, mithilfe von Datensatz-Eigenschaften:
Diese kompiliert und arbeitet ohne problem.
InformationsquelleAutor der Antwort Toon Krijthe
Den compiler ist, das Sie von der Zuordnung zu einem temporären. Das äquivalent in C# ist erlaubt, aber es hat keine Wirkung; der Rückgabewert der Rec-Eigenschaft wird eine Kopie des zugrunde liegenden Feldes, und die Zuweisung an das Feld in der Kopie ist ein nop.
InformationsquelleAutor der Antwort Barry Kelly
Einer Lösung, die ich Häufig benutze, ist zu erklären, dass die Eigenschaft als Zeiger auf den Datensatz.
Mit dabei, direkt zuweisen
Form1.Rec.A := MyInteger
arbeiten, aber auchForm1.Rec := MyRec
wird die Arbeit durch kopieren der Werte inMyRec
zu denFRec
Feld als erwartet.Der einzige Fallstrick ist hier, dass, wenn Sie wollen, um tatsächlich abrufen eine Kopie der Aufzeichnung, mit zu arbeiten, müssen Sie etwas, das wie
MyRec := Form1.Rec^
InformationsquelleAutor der Antwort vehystrix
Weil Sie implizite getter-und setter-Funktionen und Sie können nicht ändern, das Ergebnis einer Funktion, wie es ist ein const-parameter.
(Hinweis: Im Fall, verwandeln Sie den Datensatz in ein Objekt, das Ergebnis wäre eigentlich ein Zeiger, so entspricht einem var-parameter).
Wenn Sie möchten, bleiben Sie mit einem Datensatz, verwenden Sie eine temporäre variable (oder Variablen) oder die Verwendung einer WITH-Anweisung.
Sehen, die verschiedenen Verhaltensweisen, die in den folgenden code mit dem expliziten getter-und setter-Funktionen:
InformationsquelleAutor der Antwort François
Dies ist, weil die Eigenschaft auch tatsächlich erfüllt eine Funktion. Eigenschaften nur zurückgeben oder festlegen eines Werts. Es ist nicht eine Referenz oder ein Zeiger auf den Datensatz
also :
ist der gleiche wie der Aufruf einer Funktion wie folgt:
was Sie tun können, ist:
Es ist ein bisschen chaotisch, aber inhärente in dieser Art von Architektur.
InformationsquelleAutor der Antwort adrianj98
Wie andere gesagt haben - das Lesen der Eigenschaft zurück, eine Kopie der Aufzeichnung, so dass die Zuordnung der Felder nicht handeln auf der Kopie, die im Besitz von TForm1.
Eine weitere option ist das etwas wie:
Delphi dereferenzieren der PRec-pointer für Sie, so dass Dinge wie diese immer noch funktionieren:
Gibt es keine Notwendigkeit für ein schreiben Teil des Grundstücks, es sei denn, Sie wollen die swap-PRec-buffer, FRec Punkte an. Ich wirklich würde nicht empfehlen, solche swapping über eine Immobilie sowieso.
InformationsquelleAutor der Antwort otherchirps
Der einfachste Ansatz ist:
InformationsquelleAutor der Antwort Nik Todorov