AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Warum kann Record-Property nicht geschrieben werden?
Thema durchsuchen
Ansicht
Themen-Optionen

Warum kann Record-Property nicht geschrieben werden?

Ein Thema von Ares · begonnen am 4. Dez 2007 · letzter Beitrag vom 4. Dez 2007
Antwort Antwort
Ares

Registriert seit: 5. Dez 2002
269 Beiträge
 
#1

Warum kann Record-Property nicht geschrieben werden?

  Alt 4. Dez 2007, 14:38
Hallo!

Folgender Aufbau:

Delphi-Quellcode:
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;
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.

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
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#2

Re: Warum kann Record-Property nicht geschrieben werden?

  Alt 4. Dez 2007, 14:53
Zitat von Ares:
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.

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...
Delphi geht logisch vor. Wenn du folgenden Konstrukt hast, dann geht Delphi logisch so vor:

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 von Ares:
Wie kann ich also Data.Data1 etwas zuweisen?
Gar nicht. Auslesen kein Problem, aber zuweisen: Problem. Entweder eine nur-lesen Property und eine Methode als Setter oder definierst den Inhalt des Records als einzelne Properties.
  Mit Zitat antworten Zitat
Ares

Registriert seit: 5. Dez 2002
269 Beiträge
 
#3

Re: Warum kann Record-Property nicht geschrieben werden?

  Alt 4. Dez 2007, 15:01
Vielen Dank für den Hinweis.

Zitat:
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?
Natürlich nichts. Wenn ich auf LocalerRecord.Var1 zugreife wird ja auch nur Var1 verändert und nicht alle anderen Teile des Records.

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...
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Warum kann Record-Property nicht geschrieben werden?

  Alt 4. Dez 2007, 15:05
@Muetze: So richtig kann ich deine Erklärung nicht nachvollziehen.
Folgendes funktioniert ja:
1. aus dem Record eine Klasse machen
Delphi-Quellcode:
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)
2. ein dynmaischer Record:
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
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#5

Re: Warum kann Record-Property nicht geschrieben werden?

  Alt 4. Dez 2007, 15:06
Nutze doch einfach ebenfalls für dein Record eine eigene Klasse.
  Mit Zitat antworten Zitat
Benutzerbild von Kroko1999
Kroko1999

Registriert seit: 21. Apr 2005
Ort: Spremberg
455 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Warum kann Record-Property nicht geschrieben werden?

  Alt 4. Dez 2007, 15:07
ja, entweder so
type
Delphi-Quellcode:
 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;
oder so
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;
Da sprach der Stumme zum Blinden: "Du wirst sehen ..."
oder
Wer lesen kann, ist klar im Vorteil!
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: Warum kann Record-Property nicht geschrieben werden?

  Alt 4. Dez 2007, 15:16
@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.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#8

Re: Warum kann Record-Property nicht geschrieben werden?

  Alt 4. Dez 2007, 16:01
Zitat von sirius:
@Muetze: So richtig kann ich deine Erklärung nicht nachvollziehen.
Deshalb werde ich nie Tutorials schreiben: ich kann nicht erklären.

Zitat von sirius:
Folgendes funktioniert ja:
1. aus dem Record eine Klasse machen
Du bekommst die Instanz und dadurch wird nur der Instanz dieser Wert zugewiesen. Es wird aber kein Setter aufgerufen. Und genau das ist das Problem bei dem Record. Dein Beispiel braucht auch kein Setter, da du mit dem Getter die Instanz bekommst und darauf kann er frei schalten und walten - Delphi hat also einen direkten Ansprechpartner zum setzen der letzten Ebene (Data1).

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 von sirius:
2. ein dynmaischer Record:
Wie ich oben schon geschrieben hatte: wenn es ein Pointer auf den Record ist, dann hat keiner ein Problem. Auch hier kann Delphi direkt die Werte setzen. Auch hier wird im Normalfall kein Setter gebraucht, es reicht eine r/o property.

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.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Warum kann Record-Property nicht geschrieben werden?

  Alt 4. Dez 2007, 16:23
Zitat von Muetze1:
Zitat von sirius:
@Muetze: So richtig kann ich deine Erklärung nicht nachvollziehen.
Deshalb werde ich nie Tutorials schreiben: ich kann nicht erklären.
sorry.

Aber jetzt habe ich es kapiert
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz