![]() |
Warum kann Record-Property nicht geschrieben werden?
Hallo!
Folgender Aufbau:
Delphi-Quellcode:
Bei der Anweisung myObject.Data.Data1 := true; kommt es wie beschrieben zu dem Fehler "Der linken Seite kann nichts zugewiesen werden". Ich verstehe nicht warum.
type
TMyData = record Data1: Boolean; Data2: String; end; TMyObject = class(TObject) protected FTest: Boolean; FData: TMyData; public property Test: Boolean read FTest write FTest; property Data: TMyData read FData write FData; end; ... procedure Test; var myObject: TMyObject; begin myObject := TMyObject.Create; myObject.Test := true; myObject.Test := options.Data.Data1; myObject.Data.Data1 := true; //[Pascal Fehler] Der linken Seite kann nichts zugewiesen werden end; Die Property ist doch klar mit write als schreibbar markiert. Warum kann Data1 also nichts zuweisen? Mir ist dieses Problem mit Records vorher noch nie aufgefallen, allerdings habe ich auch noch nie auf diesen speziellen Fall geachtet... Wie kann ich also Data.Data1 etwas zuweisen? Besten Dank Ares |
Re: Warum kann Record-Property nicht geschrieben werden?
Zitat:
myObject.Data.Data1 := true; 1. myObject ermitteln - habe ich 2. Eigenschaft Data ermitteln - also Getter aufrufen. Also bekomme ich als Result vom Getter eine Kopie des Records. 3. Diese Kopie lokal (vergleichbar mit einer lokalen Variablen ablegen). 4. Den Wert des Elementes Data1 aus dieser lokalen Variable verarbeiten. Der Compiler weiss hierbei aber, dass es sich um eine lokale Variable handelt und markiert sie intern als konstant. Erstens weil es eine Kopie ist (der Getter hat den Record im Result und nicht als Pointer auf, somit eine Kopie). Und zum anderen kannst du keinen Teil zuweisen. Du hast einen Setter definiert für den Record - aber halt für den Record und nicht für das eine Element des Records. Was müsste Delphi machen um deine Anweisung umzusetzen? 1. Record holen (Kopie durch Getter) 2. die lokale Kopie abändern (also Data1 zuweisen) 3. die komplette Kopie durch den Setter wieder zuweisen. Grundlegend: Was soll denn mit den anderen Elementen im Record geschehen wenn du nur ein Element zuweist, aber du immer nur einen Teil veränderst? Anders gefragt: Wenn du dir ein Packet kommen lässt und darin ist eine Tasse und ein Teller. Der Postbote bringt dir das Packet und du willst aber nur die Tasse haben und den Rest wieder zurück schicken - bzw. du willst nur die Tasse annehmen. Da zeigt dir der Postbote auch einen Vogel. Entweder du nimmst das Packet ganz an und packst es aus und dann erneut neu ein und gibst es als ganzes (Packet) wieder bei der Post ab. Dann kannst du es aber nicht mehr unfrei zurück senden sondern musst erneut bezahlen. Zitat:
|
Re: Warum kann Record-Property nicht geschrieben werden?
Vielen Dank für den Hinweis.
Zitat:
Die Logik dahinter verstehe ich nicht ganz. Ein Record ist doch nur ein Konstrukt um mehrere Variablen zu einer logischen Einheit zusammen zu fassen. Warum der Zugriff auf die Teile also von Delphi nicht durchgereicht wird leuchtet mir nicht ein. Das ist aber auch egal, wichtig ist nur, dass es nicht geht :-) Ich werde mir also etwas anderes überlegen... |
Re: Warum kann Record-Property nicht geschrieben werden?
@Muetze: So richtig kann ich deine Erklärung nicht nachvollziehen.
Folgendes funktioniert ja: 1. aus dem Record eine Klasse machen
Delphi-Quellcode:
2. ein dynmaischer Record:
type
TMyData = class Data1: Boolean; Data2: String; end; TMyObject = class(TObject) protected FTest: Boolean; FData: TMyData; public property Test: Boolean read FTest write FTest; property Data: TMyData read FData write FData; end; //und FData natürlich noch instanzieren (und am Ende wieder löschen)
Delphi-Quellcode:
type
PMyData = ^TmyData TMyData = record Data1: Boolean; Data2: String; end; TMyObject = class(TObject) protected FTest: Boolean; FData: PMyData; public property Test: Boolean read FTest write FTest; property Data: PMyData read FData write FData; end; //und FData noch mit new(xxx) anlegen und mit dispose löschen |
Re: Warum kann Record-Property nicht geschrieben werden?
Nutze doch einfach ebenfalls für dein Record eine eigene Klasse.
|
Re: Warum kann Record-Property nicht geschrieben werden?
ja, entweder so
type
Delphi-Quellcode:
oder so
TMyData = record
Data1: Boolean; Data2: String; end; TMyObject = class(TObject) protected FTest: Boolean; FData: TMyData; public property Test: Boolean read FTest write FTest; property Data: TMyData read FData write FData; property Data1: Boolean read FData.Data1 write FData.Data1; //etc. end;
Delphi-Quellcode:
procedure Test;
var myObject: TMyObject; MyData: TMyData; begin myObject := TMyObject.Create; myObject.Test := true; myObject.Test := options.Data.Data1; MyData.Data1 := True; MyData.Data2 := 'Hurra'; myObject.Data := MyData; end; |
Re: Warum kann Record-Property nicht geschrieben werden?
@Ares: Wenn du als Setter ein Feld definierst, mag das ja noch einleuchten. Was soll der Compiler aber machen, wenn du eine Setter-Methode hättest? Die erwartet ja immer einen ganzen Record und nicht ein einzelnes Feld als Parameter.
|
Re: Warum kann Record-Property nicht geschrieben werden?
Zitat:
Zitat:
Der Setter ist in deinem Beispiel sogar gefährlich: Im Normalfall legt sich TMyObject die Instanz von TMyData an und hält diese die Lebzeit lang. Von daher wäre es mehr als tödlich wenn jemand dir von aussen direkt eine andere Instanz oder Nil unterschiebt. Von daher sind solche Properties generell eigentlich nur-lesen Eigenschaften. Und bei Komponenten etc. wird explizit ein Setter definiert um darin mit z.B. Assign() die Werte der Instanz zu übernehmen - aber niemals die Instanz! Zitat:
Für beide gilt: in beiden Fällen bekommst Delphi einen Zeiger auf die Zieldaten und nicht direkt die Daten in die der Nutzer schreiben möchte. Von daher kann Delphi dies erledigen, da die temporäre Variable (result vom Getter) immer nur eine Adresse enthält, nicht aber die direkten Daten, wie es bei einem direkten Record (Ausgangsfall) ist. |
Re: Warum kann Record-Property nicht geschrieben werden?
Zitat:
Aber jetzt habe ich es kapiert :mrgreen: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:33 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