Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Properties haben nach Zuweisung falsche Werte (https://www.delphipraxis.net/182495-properties-haben-nach-zuweisung-falsche-werte.html)

BlueStarHH 29. Okt 2014 12:29

Delphi-Version: 5

Properties haben nach Zuweisung falsche Werte
 
Ich habe ein Form mit einem Button. Dieser holt sich über einen Funktion einen Vornamen und Namen. Zugeweisen wird:
Adresse.Vorname := 'a';
Adresse.Name := 'b';

Wenn Vorname und Name zusammen ausgegeben wird aber "b b" angezeigt. Richtig wäre "a b". Wie kann das sein? Mit anderen Texten in der Zuweisung klappt es manchmal und manchmal nicht. Das ist sehr merkwürdig.


Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type

  TAdresse = class(TPersistent)
  private
    FVorname: string;
    FName: string;
  public
    procedure Assign(Source: TPersistent); override;

    property Vorname: string read FVorname write FVorname;
    property Name: string read FName write FName;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    function GetDebitorName: string;
    function GetReAdr: TAdresse;
  protected
    Adresse: TAdresse;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.GetReAdr: TAdresse;
begin
  Adresse.Vorname := 'a';
  Adresse.Name := 'b';

  Result := Adresse;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Adresse := TAdresse.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Adresse.Free;
end;

function TForm1.GetDebitorName: string;
begin
  Result := GetReAdr.Vorname + ' ' + GetReAdr.Name;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  caption := GetDebitorName;
end;

procedure TAdresse.Assign(Source: TPersistent);
begin
  if Source is TAdresse then
  begin
    Vorname := (Source as TAdresse).Vorname;
    Name := (Source as TAdresse).Name;
  end
  else
    inherited;
end;

end.

mkinzler 29. Okt 2014 12:34

AW: Properties haben nach Zuweisung falsche Werte
 
Es ist nie eine gute Idee in Methoden auf globale Variablen zuzugreifen.

Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Result.Vorname := 'a';
  Result.Name := 'b';
end;

BlueStarHH 29. Okt 2014 12:44

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von mkinzler (Beitrag 1277833)
Es ist nie eine gute Idee in Methoden auf globale Variablen zuzugreifen.

Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Result.Vorname := 'a';
  Result.Name := 'b';
end;

Warum nicht? Adresse ist nur innerhalb von TForm1 global. Das ist auch nur ein kleines komprimiertes Beispiel. In Wirklichkeit holt GetReAdr Daten per SQL ab und speichert diese dann in Adresse zwischen. Dafür darf Adresse nicht lokal in GetReAdr definiert sein. Denn das SQL soll nur ausgeführt werden, wenn Adresse leer ist. Sonst soll GetReAdr Adresse zurückgeben. Wenn ich sowas habe wie

property Vorname: string read FVorname write FVorname;

ist FVorname auch global in der Klasse gültig. Ähnlich wie Adresse hier.

mkinzler 29. Okt 2014 12:48

AW: Properties haben nach Zuweisung falsche Werte
 
Wenn Du es besser als ich weisst, warum fragst Du dann?

BlueStarHH 29. Okt 2014 12:55

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von mkinzler (Beitrag 1277837)
Wenn Du es besser als ich weisst, warum fragst Du dann?

Ich frage weil ich eine Lösung brauche. Deine Antwort erscheint mir aber keine Lösung zu sein. Siehe mein Edit mit dem Verweis auf die Properties. Dort arbeitet man auch mit globalen Variablen die dann entweder über Getter oder Setter zugreifbar sind. Ist hier nichts anderes. Und wie sollte man es in meinem Fall anders lösen als über eine globale Variable? Mit Deiner vorgeschlagenen Lösung geht es hier leider nicht.

BlueStarHH 29. Okt 2014 13:03

AW: Properties haben nach Zuweisung falsche Werte
 
Hier nochmal eine Ergänzung, wie GetReAdr noch SQL ausführt:

Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  if Adresse.IsEmpty then
  begin
    Query.HoleAufwändigDatenAb;
 
    Adresse.Vorname := Query.FieldByName('Vorname').asString;
    Adresse.Name := Query.FieldByName('Name').asString;
  end;

  Result := Adresse;
end;

hoika 29. Okt 2014 13:12

AW: Properties haben nach Zuweisung falsche Werte
 
Hallo,

vielleicht liefert ja dein
Query.HoleAufwändigDatenAb;

was falsches ab?

Breakpoint + Watchpoint drauf.

du kannst auch eine Set-Methode für VorName schreiben
und dort einen bedingten Breakpoint setzen, wenn 'b' übergeben wird.

Ausserdem auch hier einen Breakpoint setzen
procedure TAdresse.Assign(Source: TPersistent);

Vielleicht überschreibst du auch irgendwo Speicher -> FastMM4 benutzen.


Heiko

Uwe Raabe 29. Okt 2014 13:23

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von mkinzler (Beitrag 1277833)
Es ist nie eine gute Idee in Methoden auf globale Variablen zuzugreifen.

Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Result.Vorname := 'a';
  Result.Name := 'b';
end;

Da TAdresse eine Klasse und kein Record ist, wird das wahrscheinlich schiefgehen.

Uwe Raabe 29. Okt 2014 13:28

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von BlueStarHH (Beitrag 1277832)
Delphi-Quellcode:
function TForm1.GetDebitorName: string;
begin
  Result := GetReAdr.Vorname + ' ' + GetReAdr.Name;
end;

Durch den zweimaligen Aufruf von GetReAdr wird der Code innerhalb von GetReAdr auch zweimal ausgeführt. Ist das so beabsichtigt?

himitsu 29. Okt 2014 15:10

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von mkinzler (Beitrag 1277833)
Es ist nie eine gute Idee in Methoden auf globale Variablen zuzugreifen.

Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Result.Vorname := 'a';
  Result.Name := 'b';
end;

Sein Code war schon fast richtig, denn er "wollte" die Instanz zurückgeben, welche er in TForm1 deklatiert/erstellt hat.
Aber er hat nicht auf seinen Compiler gehört, welcher ihm bestimmt was vonwegen "Result ist nicht initialisiert" um die Ohren wirft! :roll:


[edit] :gruebel: War das
Delphi-Quellcode:
Result := Adresse;
vorhin auch schon in Post #1 ?
Nja, dein Code war zumindestens falsch, denn Result wurde nicht initialisiert.

Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Result := Adresse;
  Result.Vorname := 'a';
  Result.Name := 'b';
end;

// oder

function TForm1.GetReAdr: TAdresse;
begin
  Adresse.Vorname := 'a';
  Adresse.Name := 'b';
  Result := Adresse;
end;

BlueStarHH 29. Okt 2014 15:18

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1277843)
Zitat:

Zitat von BlueStarHH (Beitrag 1277832)
Delphi-Quellcode:
function TForm1.GetDebitorName: string;
begin
  Result := GetReAdr.Vorname + ' ' + GetReAdr.Name;
end;

Durch den zweimaligen Aufruf von GetReAdr wird der Code innerhalb von GetReAdr auch zweimal ausgeführt. Ist das so beabsichtigt?

Das stört nicht. Siehe Post #6. Dort ist ein Abfrage, verhindert das Zeitaufwändiger Code bei jedem Aufruf ausgeführt wird.

BlueStarHH 29. Okt 2014 15:19

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von hoika (Beitrag 1277840)
Hallo,

vielleicht liefert ja dein
Query.HoleAufwändigDatenAb;

was falsches ab?

Breakpoint + Watchpoint drauf.

du kannst auch eine Set-Methode für VorName schreiben
und dort einen bedingten Breakpoint setzen, wenn 'b' übergeben wird.

Ausserdem auch hier einen Breakpoint setzen
procedure TAdresse.Assign(Source: TPersistent);

Vielleicht überschreibst du auch irgendwo Speicher -> FastMM4 benutzen.


Heiko

Das ist alles OK. Alles mit Breakpoint & co geprüft. Exakt das kleine Beispiel aus Post 1 funktioniert nicht. Kannst Du Dir in ein Form kopieren und nachvollziehen. Also liegt es nicht am SQL.

BlueStarHH 29. Okt 2014 15:21

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von himitsu (Beitrag 1277867)
Zitat:

Zitat von mkinzler (Beitrag 1277833)
Es ist nie eine gute Idee in Methoden auf globale Variablen zuzugreifen.

Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Result.Vorname := 'a';
  Result.Name := 'b';
end;

Sein Code war schon fast richtig, denn er "wollte" die Instanz zurückgeben, welche er in TForm1 deklatiert/erstellt hat.
Aber er hat nicht auf seinen Compiler gehört, welcher ihm bestimmt was vonwegen "Result ist nicht initialisiert" um die Ohren wirft! :roll:


[edit] :gruebel: War das
Delphi-Quellcode:
Result := Adresse;
vorhin auch schon in Post #1 ?
Nja, dein Code war zumindestens falsch, denn Result wurde nicht initialisiert.

Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Result := Adresse;
  Result.Vorname := 'a';
  Result.Name := 'b';
end;

// oder

function TForm1.GetReAdr: TAdresse;
begin
  Adresse.Vorname := 'a';
  Adresse.Name := 'b';
  Result := Adresse;
end;

Result := Adresse; war schon immer in Post #1. Dein Lösungsvorschlag 2 steht genau so im Post #1.

BlueStarHH 29. Okt 2014 15:24

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von himitsu (Beitrag 1277867)
Nja, dein Code war zumindestens falsch, denn Result wurde nicht initialisiert.

Was genau meinst Du damit? Mit Result := Adresse; wird es initialisiert/zugewiesen. Oder sehe ich das falsch?

BlueStarHH 29. Okt 2014 15:30

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von himitsu (Beitrag 1277867)

Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Result := Adresse;
  Result.Vorname := 'a';
  Result.Name := 'b';
end;

Hab das mal eben ausprobiert: Als Vorname und Name wird dann auch 'b b' zurückgegeben. Klappt also auch nicht. Sehr merkwürdig.

himitsu 29. Okt 2014 15:33

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von BlueStarHH (Beitrag 1277874)
Zitat:

Zitat von himitsu (Beitrag 1277867)
Nja, dein Code war zumindestens falsch, denn Result wurde nicht initialisiert.

Was genau meinst Du damit? Mit Result := Adresse; wird es initialisiert/zugewiesen. Oder sehe ich das falsch?

Nicht bei Markus in Post #2 :zwinker:

Uwe Raabe 29. Okt 2014 15:39

AW: Properties haben nach Zuweisung falsche Werte
 
Ich kann das hier (XE7) reproduzieren. Es handelt sich offenbar um einen Compiler-Fehler.

Delphi-Quellcode:
var
  sn: string;
  sv: string;
begin
  sv := GetReAdr.Vorname;
  sn := GetReAdr.Name;
  result := sv + ' ' + sn;
  Result := GetReAdr.Vorname + ' ' + GetReAdr.Name;
end;
Das erste result bringt noch das richtige Ergebnis, aber beim zweiten klappts nicht.

Dejan Vu 29. Okt 2014 15:41

AW: Properties haben nach Zuweisung falsche Werte
 
Ich kann es mit D6 auch bestätigen.

Jumpy 29. Okt 2014 15:52

AW: Properties haben nach Zuweisung falsche Werte
 
Ist .Name vllt. ein reserviertes Wort in dem Zusammenhang? Zumindest wird es ja hier im Codeformatierer der DP fett blau gezeigt?

DeddyH 29. Okt 2014 16:02

AW: Properties haben nach Zuweisung falsche Werte
 
Es funktioniert auch, wenn man die Adresse in einer lokalen Variablen zwischenspeichert.
Delphi-Quellcode:
function TForm1.GetDebitorName: string;
var
  a: TAdresse;
begin
  a := GetReAdr;
  Result := a.Vorname + ' ' + a.Name;
end;

baumina 29. Okt 2014 16:12

AW: Properties haben nach Zuweisung falsche Werte
 
Mit ShortStrings funktionierts, d.h. irgendwie verpointert der sich.

Jumpy 29. Okt 2014 16:17

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von DeddyH (Beitrag 1277884)
Es funktioniert auch, wenn man die Adresse in einer lokalen Variablen zwischenspeichert.
Delphi-Quellcode:
function TForm1.GetDebitorName: string;
var
  a: TAdresse;
begin
  a := GetReAdr;
  Result := a.Vorname + ' ' + a.Name;
end;

Aber wenn man's (sinnlos) mischt wieder nicht:

Delphi-Quellcode:
function TForm1.GetDebitorName: string;
var a:Tadresse;
begin
  a:=GetReAdr;
  Result := a.Vorname + ' ' + GetReAdr.Name;
end;
Edit: Andersrum gemischt geht's dann doch wieder:
Delphi-Quellcode:
Result := GetReAdr.Vorname + ' ' + a.Name;

Uwe Raabe 29. Okt 2014 16:23

AW: Properties haben nach Zuweisung falsche Werte
 
Es hat offenbar etwas mit der internen Realisierung des String-Results als var-Parameter und der nicht-vorhandenen Referenzzählung bei String-Konstanten zu tun. Aber da mögen sich die Compiler-Leute von Embarcadero dran auslassen.

Wer schreibt den QC?

himitsu 29. Okt 2014 16:28

AW: Properties haben nach Zuweisung falsche Werte
 
Das ist ein "Fehler" im CodeHiglighting, dann das kann dieses nicht richtig auflösen, nur anhand eines Codeabschnittes.

"Name" ist nur reserviert, innerhalb einer Property-Deklaration und bei Prozedurimporten (wo es wiederum der SyntaxHighlighter in der IDE nicht hinbekommt)

BlueStarHH 29. Okt 2014 16:42

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von DeddyH (Beitrag 1277884)
Es funktioniert auch, wenn man die Adresse in einer lokalen Variablen zwischenspeichert.
Delphi-Quellcode:
function TForm1.GetDebitorName: string;
var
  a: TAdresse;
begin
  a := GetReAdr;
  Result := a.Vorname + ' ' + a.Name;
end;

Danke für den Tipp. Die Frage ist nur, funktioniert das immer? Oder nur in 99% der Fälle? Damit werden Buchnungen verarbietet. Es darf keinen Fehler geben. Wenn ich in Vorname und Name nicht 'a' und 'b' stehen habe sonderen einen anderen Wert (den ich leider nicht notiert hatte) hat es mit dem Code aus Post #1 fast immer funktioniert. Nach dem 100. Aufruf war dann Plötzlich die PLZ oder die Straße im Feld Vorname. Sowas darf nicht passieren. Es muss doch möglich sein, über eine Funktion auf eine Instanzvariable/ein Feld zuzugreifen, ohne das es komische Seiteneffekte gibt.

DeddyH 29. Okt 2014 16:53

AW: Properties haben nach Zuweisung falsche Werte
 
Da der Fehler erst durch Deinen Thread bekannt geworden ist, lehne ich mich mal weit aus dem Fenster und behaupte, dass das so immer funktionieren sollte. Haftbar lasse ich mich für diese Aussage allerdings nicht machen :angel2:

BlueStarHH 29. Okt 2014 17:15

AW: Properties haben nach Zuweisung falsche Werte
 
Selbst so geht es nicht:

Delphi-Quellcode:
property AdrProp: TAdresse read GetAdrProp write SetAdrProp;

function TForm1.GetAdrProp: TAdresse;
begin
  Adresse.Vorname := 'a';
  Adresse.Name := 'b';

  result := Adresse;
end;
Irgendwie kann ich mir nicht vorstellen, dass noch nie jemand seit Delphi 6 so eine Property mit einem Getter genutzt hat und dass das erst jetzt auffällt.

Uwe Raabe 29. Okt 2014 17:28

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von BlueStarHH (Beitrag 1277922)
Irgendwie kann ich mir nicht vorstellen, dass noch nie jemand seit Delphi 6 so eine Property mit einem Getter genutzt hat und dass das erst jetzt auffällt.

Das Problem ist offenbar die Kombination des zweimaligen Aufrufs von
Delphi-Quellcode:
GetReAdr
und der Zusammensetzung des Ergebnisses. Hier versucht der Compiler offenbar eine coole Optimierung und fällt dabei auf die Klappe. Es scheint ja gut zu funktionieren, wenn man die Strings nicht mit einem zweimaligen Aufruf der Funktion zusammensetzt. Die Felder der TAdresse-Instanz sind ja durchaus korrekt. Es ist das Concat was schief geht.

Auf den zweimaligen Aufruf hatte ich ja schon anfangs hingewiesen. Offenbar ist er nicht nur redundant sondern auch schädlich.

Der schöne Günther 29. Okt 2014 17:35

AW: Properties haben nach Zuweisung falsche Werte
 
Egal ob Optimierung an oder aus, stimmt.

Und noch interessanter: Der Fehler besteht nur beim Win32-Compiler, bei Win64 nicht. Andere Compiler kann ich nicht testen.


Könnte man folgendes als Minimalbeispiel in die QC eintragen?

Delphi-Quellcode:
program Project4;

{$APPTYPE CONSOLE}


type
   TMyClass = class
      one, two: String;
   end;

var
   globalInstance: TMyClass;

function getInstance(): TMyClass;
begin
   if not Assigned(globalInstance) then
      globalInstance := TMyClass.Create();

   globalInstance.one := 'one';
   globalInstance.two := 'two';

   Result := globalInstance;
end;

function getBoth(): String;
var
   oneCopy, twoCopy: String;
begin
   oneCopy := getInstance().one;
   twoCopy := getInstance().two;

   WriteLn( oneCopy + ' ' + twoCopy );

   Result := getInstance().one + ' ' + getInstance().two;
end;

begin
   WriteLn( getBoth() );

   // Output on DCC32:
   //one two
   //two two

   // Output on DCC64:
   //one two
   //one two
end.
Oder ginge das noch kürzer?

Jumpy 29. Okt 2014 18:00

AW: Properties haben nach Zuweisung falsche Werte
 
Wäre es denn im konkreten Fall nicht besser, das ganze Konstrukt irgendwie zu ändern?
Eine Prozedur FillAdresse, die die Felder füllt und dann die Funktion, die die gewünschten Felder "concatiert" (gibt's das?) ausgibt?

BlueStarHH 29. Okt 2014 18:06

AW: Properties haben nach Zuweisung falsche Werte
 
@Der schöne Günther: Dein Code ist eine gute Zusammenfassung und zeigt mit Delphi 2010 den Fehler. Stellt das jemand bitte in den QC ein? Ich kann mich seit 20 Minuten nicht einloggen... Danke!

Uwe Raabe 29. Okt 2014 18:08

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von Jumpy (Beitrag 1277935)
Wäre es denn im konkreten Fall nicht besser, das ganze Konstrukt irgendwie zu ändern?
Eine Prozedur FillAdresse, die die Felder füllt und dann die Funktion, die die gewünschten Felder "concatiert" (gibt's das?) ausgibt?

Man könnte z.B. die Funktion GetDebitorName in TAdresse verlagern. Es gibt -zig Möglichkeiten das Problem zu umgehen - deswegen ist es bisher wohl auch nicht aufgefallen.

Dejan Vu 29. Okt 2014 18:20

AW: Properties haben nach Zuweisung falsche Werte
 
Das Ungewöhnliche ist wohl das hier:
Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Adresse.Vorname := 'a';
  Adresse.Name := 'b';
  Result := Adresse;
end;
Die Zuweisung von 'a' und 'b' im 'Getter' der ReAdr.

Man würde die Eigenschaften der Adresse einmalig setzen z.B. per LazyLoad.
Oder man würde gleich eine protected Property aus der Adresse machen.

bernau 29. Okt 2014 18:32

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von himitsu (Beitrag 1277891)
Das ist ein "Fehler" im CodeHiglighting, dann das kann dieses nicht richtig auflösen, nur anhand eines Codeabschnittes.

"Name" ist nur reserviert, innerhalb einer Property-Deklaration und bei Prozedurimporten (wo es wiederum der SyntaxHighlighter in der IDE nicht hinbekommt)


Auch wenn es in dem Fall OK ist, wenn "Name" als Property verwendet wird. Ich würde diese Bezeichnung nicht verwenden. Habe früher schon oft nach Fehlern gesucht, weil "Name" dann doch häufiger in Klassen verwendet wird.

Ich verwende für So etwas immer "Vorname" und "Nachname". Das ist dann eindeutiger.

Aber natürlich Geschmackssache.

BlueStarHH 29. Okt 2014 19:24

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von Dejan Vu (Beitrag 1277939)
Das Ungewöhnliche ist wohl das hier:
Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Adresse.Vorname := 'a';
  Adresse.Name := 'b';
  Result := Adresse;
end;
Die Zuweisung von 'a' und 'b' im 'Getter' der ReAdr.

Man würde die Eigenschaften der Adresse einmalig setzen z.B. per LazyLoad.
Oder man würde gleich eine protected Property aus der Adresse machen.

LazyLoad wird im realen Code verwendet. Fehler tritt trotzdem auf. Auch mit einer protected Property. Das hier ist nun ein komprimierter Code um den Fehler zu zeigen...

Dejan Vu 29. Okt 2014 20:37

AW: Properties haben nach Zuweisung falsche Werte
 
Lazy Load sorgt dafür, das solche Zuweisungen nur einmal durchgeführt werden.
Delphi-Quellcode:
// Also so gehts:
Function TForm1.GetReAdr: TAdresse;
Begin
  If fAddress = Nil Then Begin
    Adresse.Vorname := 'a';
    Adresse.Name := 'b';
    fAddress := Adresse;
  End;
  Result := fAddress;
End;

// Und so auch
Function TForm1.GetReAdr: TAdresse;
Begin
  If not fInitialized Then Begin
    Adresse.Vorname := 'a';
    Adresse.Name := 'b';
    fInitialized := True;
  End;
  Result := Adresse;
End;
Allgemein ist das LazyLoad-Pattern für Properties so:
Delphi-Quellcode:
Function TMyClass.GetProperty : TSomeValue;
Begin
  if fProperty=nil then
    fProperty := CreateSomeValue;
  result := fProperty;
End;
Damit wird nur beim Zugriff, und dann nur beim ersten, instantiiert. Früher nannte man das 'Fetch on demand'. Heute eben 'lazy load'. Und damit schlägt man dem blöden Compiler ein Schnippchen.

BlueStarHH 29. Okt 2014 21:02

AW: Properties haben nach Zuweisung falsche Werte
 
Wie gesagt LazyLoad wird verwendet (siehe Post #6) und ändert am Problem nichts...

Sir Rufo 29. Okt 2014 21:31

AW: Properties haben nach Zuweisung falsche Werte
 
Das Problem ist die Referenz-Zählung für die Strings. Bei jeder Zuweisung wird der String an eine andere Speicheradresse geschrieben und die alte Speicheradresse wird als frei markiert.

Es taucht nicht auf, wenn man für die Eigenschaften
Delphi-Quellcode:
Name
und
Delphi-Quellcode:
Vorname
einen Getter benutzt
Delphi-Quellcode:
type
  TAdresse = class
  private
    FVorname: string;
    FName: string;
    function GetName: string;
    function GetVorname: string;
  public
    property Vorname: string read GetVorname write FVorname;
    property Name: string read GetName write FName;
  end;
Weiterhin taucht es nicht auf, wenn man die Adresse so zusammensetzt
Delphi-Quellcode:
function TFoo.GetFullName : string;
begin
  Result := GetAdresse.Vorname + GetAdresse.Nachname;
end;
Und wenn man sich mal spasseshalber die Pointer auf die Variablen holt
Delphi-Quellcode:
function TTest.GetFullName : string;
var
  LVorname, LName : PChar;
begin
  LVorname := PChar( GetAdresse.Vorname );
  // jetzt zeigt der Debugger den korrekten Vornamen bei LVorname an
  LName := PChar( GetAdresse.Name );
  // ab jetzt steht in LVorname und LName der gleiche Wert, weil nun die Pointer an die gleiche Stelle zeigen
  Result := GetAdresse.Vorname + GetAdresse.Nachname;
end;
Dieses ist aber eher Zufall, da die beiden Speicherstellen abwechselnd belegt werden, was wir mit folgendem Code überprüfen können
Delphi-Quellcode:
function TTest.GetFullName: string;
var
  LName1, LVorname, LName2 : PChar;
begin
{1}  LName1 := PChar( GetAdresse.Name );
{2}  LVorname := PChar( GetAdresse.Vorname );
{3}  LName2 := PChar( GetAdresse.Name );
end;
Hier die Inhalte jeweils nach der Codezeile
NrLName1LVornameLName2
{1}Lustig--
{2}LustigPeter-
{3}PeterLustigLustig
oder wenn man sich die Pointer-Adressen anschaut, dann (Beispielswerte, die ändern sich eh je nach Start)
NrLName1LVornameLName2
{1}$420C--
{2}$420C$422C-
{3}$420C$422C$422C
Oder hier einmal schön den Wechselreigen mit den Adressen bei der Zuweisung
Codezeile+ Adresse- Adresse
Adresse.Vorname := 'Peter';A 
Adresse.Name := 'Lustig';B 
Zugriff auf Vorname => A  
Adresse.Vorname := 'Peter';CA
Adresse.Name := 'Lustig';AB
Zugriff auf Name => A  
Adresse.Vorname := 'Peter';BC
Adresse.Name := 'Lustig';CA
Der Vollständigkeit halber sei noch erwähnt, dass dieses hier
Delphi-Quellcode:
function TTest.GetFullNameReverse: string;
begin
  Result := GetAdresse.Name + ' ' + GetAdresse.Vorname;
end;
natürlich einwandfrei funktioniert. Warum?
Codezeile+ Adresse- Adresse
Adresse.Vorname := 'Peter';A 
Adresse.Name := 'Lustig';B 
Zugriff auf Name => B  
Adresse.Vorname := 'Peter';CA
Adresse.Name := 'Lustig';AB
Zugriff auf Vorname => C  
Adresse.Vorname := 'Peter';BC
Adresse.Name := 'Lustig';CA
;) (funktioniert aber auch nur, weil der Speicherbereich noch nicht überschrieben wurde)

Dejan Vu 29. Okt 2014 21:37

AW: Properties haben nach Zuweisung falsche Werte
 
Zitat:

Zitat von BlueStarHH (Beitrag 1277973)
Wie gesagt LazyLoad wird verwendet (siehe Post #6) und ändert am Problem nichts...

Bei mir schon (habs gerade probiert). Es ist ja nichts anderes, als mein 2.Vorschlag. Und ich habe deinen Code aus Post #6 kopiert. Geht. Vielleicht ist dein 'IsInitialized' nicht korrekt.

@Sir Rufo: Nee, oder? Verrückt! Tolle Analyse!

Gut, das ich bei C# bin. :mrgreen:

Sir Rufo 29. Okt 2014 22:01

AW: Properties haben nach Zuweisung falsche Werte
 
Unter Win64 ist der Pointer-Reigen auch zu beobachten, allerdings sind die Ergebnisse immer korrekt.

Somit wird unter Win64 wohl der Speicherbereich sofort kopiert und bei Win32 wird sich der Pointer gemerkt und zum Schluss zusammenkopiert (mit dem bekannten Ergebnis).

Nur so eine Vermutung und ich will da jetzt auch nicht zu sehr in die Tiefe gehen :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:50 Uhr.
Seite 1 von 2  1 2      

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 by Thomas Breitkreuz