Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Superobject und Objekte (https://www.delphipraxis.net/192575-superobject-und-objekte.html)

Ghostwalker 2. Mai 2017 05:02

Superobject und Objekte
 
moinmoin,

bin grad ein wenig am verzweifeln. Ich hab ein Objekt, das seine Daten in Form eines Records enthält

Delphi-Quellcode:
  TOptionsOpts = (ooOne,ooTwo,ooThree);
  TOptionsData = record
                   fval1 : widestring;
                   fval2 : integer;
                   fval3 : Double;
                   fval4 : TOptionsOpts;
  end;

  TOptions = class
    private
       fdata : TOptionsData;

    protected
    public
       procedure ClearData;
       Procedure ResetToDefault;
       Procedure SaveToJson(filename:WideString);
       Procedure LoadFromJson(filename:WideString);
    published
      Property Value1:WideString read fdata.fval1 write fdata.fval1;
      Property Value2:Integer read fdata.fval2 write fdata.fval2;
      Property Value3:Double read fdata.fval3 write fdata.fval3;
      Property value4:TOptionsOpts read fdata.fval4 write fdata.fval4;
  end;
Soweit so gut. Das Object soll seine Daten nun in eine Datei (JSON-Format) speichern und ggf. auch wieder laden.

Speichern:
Delphi-Quellcode:
procedure TOptions.SaveToJson(filename: WideString);
var
  ctx : TSuperRttiContext;
  obj : ISuperObject;
begin
  ctx := TSuperRttiContext.Create;
  obj := ctx.AsJson<TOptionsData>(fdata);
  obj.SaveTo(filename);
  ctx.free;
end;
Das funktioniert auch soweit ganz gut. Aber das laden:

Delphi-Quellcode:
procedure TOptions.LoadFromJson(filename: WideString);
var
  ctx : TSuperRttiContext;
  ws : Widestring;
  ss : TStringStream;
  fs : TFileStream;

begin
  fs := TFileStream.Create(filename,fmOpenRead);
  ss := TStringStream.Create;
  ss.LoadFromStream(fs);
  ws := ss.DataString;
  fs.Free;
  ss.Free;
  ctx := TSuperRttiContext.Create;
  fdata := ctx.AsType<TOptionsData>(SO(ws));
  ctx.Free;
end;
mag so garnicht. bei ctx.AsType<TOptionsdata> bekomm ich einen marshalling-error. Kann mir da jemand weiterhelfen ? Danke schonmal.

haentschman 2. Mai 2017 05:35

AW: Superobject und Objekte
 
Moin...:P
Warum steht ihr so auf Records. In Verbindung mit Klassen und Properties gibt es immer Probleme. Imho erst Recht mit Serialisieren. (Sichwort Beispiel: Der linken Seite kann nichts zugewiesen werden.)

Versuch es mal hiermit:
Delphi-Quellcode:
type
  TOptionsOpts = (ooOne, ooTwo, ooThree);

  TOptionsData = class
  private
    FVal1: WideString;
    FVal2: Integer;
    FVal3: Double;
    FVal4: TOptionsOpts;
  public
    property Val1: WideString read FVal1 write FVal1;
    property Val2: Integer read FVal2 write FVal2;
    property Val3: Double read FVal3 write FVal3;
    property Val4: TOptionsOpts read FVal4 write FVal4;
  end;

  TOptions = class
  private
    FData: TOptionsData;
  protected
  public
    procedure ClearData;
    procedure ResetToDefault;
    procedure SaveToJson(Filename: WideString);
    procedure LoadFromJson(Filename: WideString);
  published
    constructor Create;
    destructor Destroy; override;
    property Data: TOptionsData read FData write FData;
  end;

implementation

constructor TOptions.Create;
begin
  FData := TOptionsData.Create;
end;

destructor TOptions.Destroy;
begin
  FData.Free;
  inherited;
end;
...

Ghostwalker 2. Mai 2017 07:59

AW: Superobject und Objekte
 
Zitat:

Zitat von haentschman (Beitrag 1369746)
Moin...:P
Warum steht ihr so auf Records. In Verbindung mit Klassen und Properties gibt es immer Probleme. Imho erst Recht mit Serialisieren. (Sichwort Beispiel: Der linken Seite kann nichts zugewiesen werden.)

Weil:

* Record ->Strukturtype zu reinen Speicherung von strukturierten Daten
* Class -> Strukturtype für Objekte (Daten+Methoden zu deren Verarbeitung)

Im Ursprungsversuch hatte ich die Eigenschaften ja eigentlich auch direkt in TOptions, was aber zum gleichen Problem führte.
Zitat:

Zitat von haentschman (Beitrag 1369746)
Versuch es mal hiermit:
Delphi-Quellcode:
type
  TOptionsOpts = (ooOne, ooTwo, ooThree);

  TOptionsData = class
  private
    FVal1: WideString;
    FVal2: Integer;
    FVal3: Double;
    FVal4: TOptionsOpts;
  public
    property Val1: WideString read FVal1 write FVal1;
    property Val2: Integer read FVal2 write FVal2;
    property Val3: Double read FVal3 write FVal3;
    property Val4: TOptionsOpts read FVal4 write FVal4;
  end;

  TOptions = class
  private
    FData: TOptionsData;
  protected
  public
    procedure ClearData;
    procedure ResetToDefault;
    procedure SaveToJson(Filename: WideString);
    procedure LoadFromJson(Filename: WideString);
  published
    constructor Create;
    destructor Destroy; override;
    property Data: TOptionsData read FData write FData;
  end;

implementation

constructor TOptions.Create;
begin
  FData := TOptionsData.Create;
end;

destructor TOptions.Destroy;
begin
  FData.Free;
  inherited;
end;
...

->Marshalling error beim laden.

mjustin 2. Mai 2017 08:21

AW: Superobject und Objekte
 
Zitat:

Zitat von Ghostwalker (Beitrag 1369752)
Weil:
* Record ->Strukturtype zu reinen Speicherung von strukturierten Daten
* Class -> Strukturtype für Objekte (Daten+Methoden zu deren Verarbeitung)

Wenn ich strukturierte Daten speichern will, nehme ich einfach eine Class ohne Methoden ;)
Sind records nicht eher etwas für maschinennahe Spezialfälle, wenn man im Speicher ganz bestimmte Bytefolgen benötigt?

Ghostwalker 2. Mai 2017 08:39

AW: Superobject und Objekte
 
Nein, ist eine Frage der effizients. Eine Klasse hat nunmal wesentlich mehr Informationen zu speichern (auch von der internen Verwaltung her) als ein Record.

Schau dir einfach mal TObject an (davon wird jede Klasse abgeleitet). Dann wirst du sehen das z.B.

Delphi-Quellcode:
  Type
   TPoint = record
     x,y : integer
   end;
weniger Speicher verbrät als

Delphi-Quellcode:
  Type
   TPoint = class
   public
     x,y : integer;
   end;
Aber, zurück zum Thema, ändert das nichts am Problem.

Uwe Raabe 2. Mai 2017 09:16

AW: Superobject und Objekte
 
Zitat:

Zitat von mjustin (Beitrag 1369756)
Sind records nicht eher etwas für maschinennahe Spezialfälle, wenn man im Speicher ganz bestimmte Bytefolgen benötigt?

Das war früher vielleicht mal der Fall - dort meist auch noch mit dem Attribut
Delphi-Quellcode:
packed
und diversen Filler-Bytes.

Records haben durchaus ihre Berechtigung in modernem Code. Sei es, weil man Instantiation-by-Declaration, Operator-Overloading oder Copy-On-Assign nutzen möchte. Mal eben den Inhalt eines Records lokal sichern und wieder herstellen geht in der Regel viel einfacher als bei Klassen. Dazu bieten sie (wie Klassen) auch Methoden und Eigenschaften.

Ghostwalker 2. Mai 2017 13:51

AW: Superobject und Objekte
 
Jap. Das unter anderem auch :)

Hat jetzt aber nix mit dem Problem zu tun.

Ghostwalker 4. Mai 2017 04:50

AW: Superobject und Objekte
 
ok...zurück zum Thema:

jemand noch eine Idee woran das liegen könnte ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:46 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