AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Record- oder Klassenfelder als property zuweisen und lesen, wie?
Thema durchsuchen
Ansicht
Themen-Optionen

Record- oder Klassenfelder als property zuweisen und lesen, wie?

Ein Thema von delphifan2004 · begonnen am 24. Feb 2023 · letzter Beitrag vom 26. Feb 2023
Antwort Antwort
delphifan2004

Registriert seit: 26. Nov 2004
Ort: Dresden
274 Beiträge
 
Delphi 10.3 Rio
 
#1

Record- oder Klassenfelder als property zuweisen und lesen, wie?

  Alt 24. Feb 2023, 21:04
Hallo,

bitte guckt nicht zu sehr auf meine Ausdrucksweise, ich weiß echt nicht weiter. Fragestellung unten.

Delphi-Quellcode:
  { TDataItem }

  TDataItem = record
    DataType: TDataType;
    Field1: Typ1;
    Field2: Typ2; //Für mehrere Datenfelder
    Fieldnum: Integer; //Feldnummer
    case Longword of
     0: (BinData : Pointer); //für binäre Daten
     1: (dworddata: Longword); //für ganzzahlige positive Zahlenwerte
     2: (Int32data: Integer); //für ganzzahlige positive wie negative Zahlenwerte
     3: (Floatdata: Double); //für Gleitkommazahlen
     4: (Int16data: smallint); //für 16 Bit Integerzahlen
     5: (Strgdata : PString); //für Strings
  end;


  { TGenericItem }

  TGenericItem = class(TObject)
  private
    FData: TDataItem;
    function GetDataType: TDataType;
    function GetData: TDataItem;
    procedure SetDataType(AValue: TDataType);
    procedure SetData(AValue: TDataItem);
  public

    constructor Create;
    destructor Destroy; override;

    property Data: TDataItem read GetData write SetData;

  end;

  { TCustomColumn }

  TCustomColumn = class(TComponent)
  private
    FLeft: Integer;
    FTop: Integer;
    FItem: TGenericItem;
    procedure SetItem(AValue: TGenericItem);
  public
    constructor Create(AOwner: TComponent);
    property [B]Item[/B]: TGenericItem read FItem write SetItem;
  end;
Wie kann ich jetzt mein Item in TCustomColumn lesen und schreiben, ohne dass Exceptions geworfen werden.

Delphi-Quellcode:
function TGridColumn.GetWidth: Integer;
var AItem: TDataItem;
begin
  AItem := Item.Data; //das hier wird nicht akzeptiert, wie mache ich das besser? Wenn ich an die Eigenschaft nur den ganzen Datentyp zuweisen kann, brauche ich ja die Daten der übrigen Felder
                                 //die hier nicht beeinflusst werden. Ok, beim Getter nicht aber beim Setter.
  Result := AItem.Fieldnum; //sowas in der Art will ich am Ende haben, für alle im Datentyp enthaltenen Felder
end;
Wie kann ich bei zusammengesetzten Typen die Daten als Eigenschaft lesen uns schreiben. Sorry, ich weiß echt nicht wie ich es anders ausdrücken soll.

Am Ende will ich Record- und Klassentypen als property lesen und schreiben und dabei auch einzelne Datenfelder dieser Typen verändern können, wie im Beispiel die Fieldnum oder die Inhalte von Field1 und Field2, wobei ich als Interface nur die property mit dem gesamten Datentyp habe, der die Felder enthält.
  Mit Zitat antworten Zitat
MPeters

Registriert seit: 20. Nov 2022
9 Beiträge
 
#2

AW: Record- oder Klassenfelder als property zuweisen und lesen, wie?

  Alt 25. Feb 2023, 08:53
Alles zu kompliziert. Ich baue solche Felder grundsätzlich direkt in meine Klasse ein, vermeide solche komplexen Konstrukte.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Record- oder Klassenfelder als property zuweisen und lesen, wie?

  Alt 25. Feb 2023, 11:06
Mit einem Pointer auf TDataItem, den die Property zurück liefert, sollte es gehen.

Ich persönlich würde das ganze aber komplett mit Generics und Klassen umsetzen. Mal so ins Blaue getippt, das sollte kompilieren:
Delphi-Quellcode:
type
  TDataItem = class

  end;

  TDataItem<T> = class(TDataItem)
  private
    FData: T;
  public
    constructor Create(const AValue: T);
    procedure SetData(const AValue: T);
    function GetData: T;
  end;

  TCustomColumn = class(TComponent)
  private
    FItem: TDataItem;
  public
    procedure SetItem<T>(const AValue: T);
    function GetItem<T>: T;
  end;

...

function TCustomColumn.GetItem<T>: T;
begin
  if Assigned(FItem) and (FItem is TDataItem<T>) then
    Result := TDataItem<T>(FItem).GetData
  else
    raise Exception.Create('Falscher Typ');
end;

procedure TCustomColumn.SetItem<T>(const AValue: T);
begin
  FItem.Free;
  FItem := TDataItem<T>.Create(AValue);
end;

constructor TDataItem<T>.Create(const AValue: T);
begin
  FData := AValue;
end;

function TDataItem<T>.GetData: T;
begin
  Result := FData;
end;

procedure TDataItem<T>.SetData(const AValue: T);
begin
  FData := AValue;
end;

...

procedure Example;
var
  a: TCustomColumn;
begin
  a := TCustomColumn.Create(nil);
  a.SetItem<Integer>(42);
  ShowMessage(a.GetItem<Integer>.ToString);
  a.SetItem<string>('42');
  ShowMessage(a.GetItem<string>);
end;
Alternativ:
Delphi-Quellcode:
function TCustomColumn.GetItem<T>: T;
begin
  if Assigned(FItem) then
    Result := (FItem as TDataItem<T>).GetData
  else
    Result := TValue.Empty.AsType<T>;
end;
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von ConnorMcLeod
ConnorMcLeod

Registriert seit: 13. Okt 2010
Ort: Bayern
490 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Record- oder Klassenfelder als property zuweisen und lesen, wie?

  Alt 25. Feb 2023, 11:21
Denke ich zu einfach? Bei mir funkt es ...
Delphi-Quellcode:
function TTemplateApp.GetWidth: Integer;
var
  LoColumn : TCustomColumn;
  LoDataItem: TGenericItem;
begin
  Result := 0;
  LoColumn := TCustomColumn.Create(nil);
  LoDataItem := TGenericItem.Create;
  try
    LoColumn.Item := LoDataItem;
    Result := LoColumn.Item.Data.Int32data;
  finally
    FreeAndNil(LoDataItem);
    FreeAndNil(LoColumn);
  end;
end;
Nr.1 Delphi-Tool: [F7]
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Record- oder Klassenfelder als property zuweisen und lesen, wie?

  Alt 25. Feb 2023, 11:45
Denke ich zu einfach? Bei mir funkt es ...
Versuch das mal zu schreiben. Du bekommst den Record über die property, aber dadurch ist er readonly. Wenn man den Pointer zurück liefert, wie ich geschrieben habe, müsste es aber gehen.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von ConnorMcLeod
ConnorMcLeod

Registriert seit: 13. Okt 2010
Ort: Bayern
490 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Record- oder Klassenfelder als property zuweisen und lesen, wie?

  Alt 25. Feb 2023, 13:05
Verstehe, es geht um die Zuweisung. Das habe ich im Anfangsbeispiel nicht gesehen.
Ein Interimsrecord tut's auch.

Delphi-Quellcode:
function TTemplateApp.GetWidth: Integer;
var
  LoColumn : TCustomColumn;
  LoDataItem: TGenericItem;
  LrData : TDataItem;
begin
  Result := 0;
  LoColumn := TCustomColumn.Create(nil);
  LoDataItem := TGenericItem.Create;
  try // Speicherschutz
    LoColumn.Item := LoDataItem;

    LrData := LoDataItem.Data;
    LrData.Int32data := 42;
    LoDataItem.Data := LrData;

    Result := LoColumn.Item.Data.Int32data;
  finally // aufräumen
    FreeAndNil(LoDataItem);
    FreeAndNil(LoColumn);
  end;
end;
Nr.1 Delphi-Tool: [F7]
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Record- oder Klassenfelder als property zuweisen und lesen, wie?

  Alt 25. Feb 2023, 16:35
Das erfüllt die Anforderung nicht so ganz:
Am Ende will ich Record- und Klassentypen als property lesen und schreiben und dabei auch einzelne Datenfelder dieser Typen verändern können, wie im Beispiel die Fieldnum oder die Inhalte von Field1 und Field2, wobei ich als Interface nur die property mit dem gesamten Datentyp habe, der die Felder enthält.
Davon abgesehen fände ich eine solche Lösung beim Neuentwurf einer Klasse nicht schön.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
delphifan2004

Registriert seit: 26. Nov 2004
Ort: Dresden
274 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Record- oder Klassenfelder als property zuweisen und lesen, wie?

  Alt 25. Feb 2023, 19:51
Danke @jaenicke, da werd ich das mal so umsetzen, wie in Beitrag #3, das compiliert. Bei Fragen oder endgültig gefundener Lösung melde ich mich wieder. Da werd ich mich also nun mal mit Generics beschaäftigen.


@ConnorMcLeod: so wollte ich das ja zuerst machen, funkt aber bei mir nicht.

Geändert von delphifan2004 (25. Feb 2023 um 19:58 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von ConnorMcLeod
ConnorMcLeod

Registriert seit: 13. Okt 2010
Ort: Bayern
490 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Record- oder Klassenfelder als property zuweisen und lesen, wie?

  Alt 26. Feb 2023, 11:33
Gut, wenn die Lösung paßt. Ich bin auch ein Freund von Pointern. Aber die Dereferenziererei und Casterei verlangt eiserne Disziplin
Nr.1 Delphi-Tool: [F7]
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#10

AW: Record- oder Klassenfelder als property zuweisen und lesen, wie?

  Alt 26. Feb 2023, 13:02
Aber die Dereferenziererei und Casterei verlangt eiserne Disziplin
Ist doch gar nicht nötig:
Delphi-Quellcode:
type
  PDataItem = ^TDataItem;
...
type
  TGenericItem = class(TObject)
  private
    FData: TDataItem;
  ...
    property Data: PDataItem read GetData;
...
function TGenericItem.GetData: PDataItem;
begin
  Result := @FData;
end;
...
var Item: TGenericItem;
...
  if Item.Data.Fieldnum < 0 then
    Item.Data.FieldNum := 1;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  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 12:03 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