AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Generische Array-Propertys

Ein Thema von zappa2 · begonnen am 23. Feb 2021 · letzter Beitrag vom 23. Feb 2021
Antwort Antwort
zappa2

Registriert seit: 12. Apr 2015
8 Beiträge
 
#1

Generische Array-Propertys

  Alt 23. Feb 2021, 10:45
Ich kämpfe gerade mit dem Verständnis von Generics. Die Deklaration des generischen offenen Arrays klappt klaglos:

Code:
type
  TValue<T> = class
  protected
    a: array of T;
    function GetT(const Index: Integer): T;
    procedure SetT(const Index: Integer; const Value: T);
  end;

  TAStr = TValue<String>;
  TAInt = TValue<Integer>;

..

implementation

function TValue<T>.GetT(const Index: Integer): T;
begin
  Result := a[Index];
end;

procedure TValue<T>.SetT(const Index: Integer; const Value: T);
begin
  a[Index] := Value;
end;
Das läuft, so weit so gut. Wenn ich das jetzt aber anwenden will, klappt nix mehr.
Simples Beispiel:

Code:
  TTest = class
  private
    aStr: TAStr;
    aInt: TAInt;
  published
    property s0: String index 0 read GetT<String> write SetT<String> ;
    property i0: Integer index 0 read GetT<Integer> write SetT<Integer> ;
  end;
Wo liegt mein Denkfehler? Wie komme ich denn nun an die Items ran?
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.534 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Generische Array-Propertys

  Alt 23. Feb 2021, 10:51
Definiere "klappt nix mehr". Die Properties sind vom Typ einer Klasse, werden sie auch instanziert? Und wieso sind die Getter und Setter der umgebenden Klasse TTest generisch?
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
zappa2

Registriert seit: 12. Apr 2015
8 Beiträge
 
#3

AW: Generische Array-Propertys

  Alt 23. Feb 2021, 11:02
Klappt nix mehr heißt nur, dass ich nicht herausbekomme, wie ich auf die jeweiligen Items nun zugreifen kann.

Wenn die Getter und Setter nicht generisch sind, brauche ich doch gar keine Generics.
Dann kann ich auch einfach Klassen für jeden Array-Typ schreiben, die ihre Get/Set einzeln bekommen. Das kann ich aber schon seit TurboPascal.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.017 Beiträge
 
Delphi 12 Athens
 
#4

AW: Generische Array-Propertys

  Alt 23. Feb 2021, 11:05
Erstmal: keine SetLength?

Und read/write greift auf Methoden in der Klasse zu, welche es in deinem TTest garnicht gibt. (was dir garantiert der Compiler auch sagt)
Von den Methoden in den Sub-Klassen weiß niemand etwas.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.058 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Generische Array-Propertys

  Alt 23. Feb 2021, 11:20
Delphi-Quellcode:
program Project2;

{$APPTYPE CONSOLE}

{$R *.res}


uses
  System.SysUtils,
  System.Math;

type
  TValue<T> = class
  protected
    a: TArray<T>;
    function GetT(const Index: Integer): T;
    procedure SetT(const Index: Integer; const Value: T);
  end;

  TAStr = class(TValue<string>)
  public
    property s0: string index 0 read GetT write SetT;
  end;

  TAInt = class(TValue<Integer>)
  public
    property i0: Integer index 0 read GetT write SetT;
  end;

  TTest = class
  private
    aStr: TAStr;
    aInt: TAInt;
  public
    constructor Create();
    destructor Destroy; override;
  public
    property MyStrings: TAStr read aStr;
    property MyIntegers: TAInt read aInt;
  end;

function TValue<T>.GetT(const Index: Integer): T;
begin
  if InRange(Index, System.Low(a), System.High(a)) then
  begin
    Result := a[Index];
  end
  else
  begin
    Result := System.Default(T);
  end;
end;

procedure TValue<T>.SetT(const Index: Integer; const Value: T);
begin
  if Index >= Length(a) then
  begin
    SetLength(a, Index + 1);
  end;
  a[Index] := Value;
end;

constructor TTest.Create;
begin
  inherited;
  aStr := TAStr.Create;
  aInt := TAInt.Create;
end;

destructor TTest.Destroy;
begin
  aStr.Free;
  aInt.Free;
  inherited;
end;

procedure TestStrings;
var
  MyStringValue: TAStr;
begin
  MyStringValue := TAStr.Create;
  MyStringValue.s0 := 'Hello World';
  Writeln(MyStringValue.s0);
  MyStringValue.Free;
end;

procedure TestIntegers;
var
  MyIntegerValue: TAInt;
begin
  MyIntegerValue := TAInt.Create;
  MyIntegerValue.i0 := 0815;
  Writeln(MyIntegerValue.i0);
  MyIntegerValue.Free;
end;

procedure TestTest;
var
  MyTest: TTest;
begin
  MyTest := TTest.Create;
  MyTest.aStr.s0 := 'Huhu';
  MyTest.aInt.i0 := 123;
  Writeln(MyTest.aStr.s0);
  Writeln(MyTest.aInt.i0);
  MyTest.Free;
end;

begin
  ReportMemoryLeaksOnShutdown := True;
  try
    TestStrings;
    TestIntegers;
    TestTest;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.
  Mit Zitat antworten Zitat
zappa2

Registriert seit: 12. Apr 2015
8 Beiträge
 
#6

AW: Generische Array-Propertys

  Alt 23. Feb 2021, 11:36
Erst mal vielen Dank für Eure Antworten!

Natürlich gibt es auch ein SetLength usw., der Code dazu ist für meine Frage aber nicht relevant.

Deshalb habe ich hier lediglich den Ausschnitt kopiert, der für meine Frage relevant ist:

Wie greift man in Klassen, die Gebrauch von diesen Generischen Klassen macht, auf die einzelnen Items zu?

Zu gut deutsch, was muss hier stehen, damit ich die Property-Zugriffe compilieren kann?

Code:
TTest = class
  private
    aStr: TAStr;
    aInt: TAInt;
  published
    property s0: String index 0 read GetT<String> write SetT<String> ;     <=========== hier steckt der Fehler; im read/write
    property i0: Integer index 0 read GetT<Integer> write SetT<Integer> ;
  end;
@TiGü:

Das
property MyStrings: TAStr read aStr;
property MyIntegers: TAInt read aInt;
weiß ich natürlich, kein Ding.

Aber ich benötige wirklich die einzelnen Items in den Arrays als published propertys. Es baut sich hiernach eine Klassenhierarchie auf, die unterschiedlichste (sowohl Benamung als auch Anzahlen) Strings, Integer usw. benötigen, deren Namen mittels RTTI für nachgelagerte Operationen benötigt werden. Ohne Generics habe ich das Zeugs ja schon, aber ich schreibe diese Zugriffe und Prüfungen für jeden Typ separat derzeit. Das wollte ich gern generisch (für mich übersetzt: abstrakt?) machen, damit eine Änderung sofort für alle Typen funzt.
  Mit Zitat antworten Zitat
zappa2

Registriert seit: 12. Apr 2015
8 Beiträge
 
#7

Brett vorm Kopf

  Alt 23. Feb 2021, 12:46
Heureka, man ich hatte ja so ein Brett vorm Kopf

Klar, es muss natürlich einmal noch ein simpler Setter/Getter pro benutztem Array geschrieben werden.

Mann, wie kann man nur
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.058 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Generische Array-Propertys

  Alt 23. Feb 2021, 12:49
Ah, du hast die Antwort schon selber gefunden.

Aber falls der Nächste in achtdreiviertel Jahren beim Googlen hier lang kommt:

Obigen Code aus meiner Antwort ergänzen mit:
Delphi-Quellcode:
type
  TTest = class
  private
    aStr: TAStr;
    aInt: TAInt;
  public
    constructor Create;
    destructor Destroy; override;
    function GetInteger(const Index: Integer): Integer;
    function GetString(const Index: Integer): String;
    procedure SetInteger(const Index, Value: Integer);
    procedure SetString(const Index: Integer; const Value: String);
  published
    property s0: String index 0 read GetString write SetString;
    property i0: Integer index 0 read GetInteger write SetInteger ;
  end;

...

constructor TTest.Create;
begin
  inherited;
  aStr := TAStr.Create;
  aInt := TAInt.Create;
end;

destructor TTest.Destroy;
begin
  aStr.Free;
  aInt.Free;
  inherited;
end;

function TTest.GetInteger(const Index: Integer): Integer;
begin
  Result := Self.aInt.i0;
end;

function TTest.GetString(const Index: Integer): String;
begin
  Result := Self.aStr.s0;
end;

procedure TTest.SetInteger(const Index, Value: Integer);
begin
  Self.aInt.i0 := Value;
end;

procedure TTest.SetString(const Index: Integer; const Value: String);
begin
  Self.aStr.s0 := Value;
end;
Delphi-Quellcode:
procedure TestTest;
var
  MyTest: TTest;
begin
  MyTest := TTest.Create;
  MyTest.s0 := 'Huhu';
  MyTest.i0 := 123;
  Writeln(MyTest.s0);
  Writeln(MyTest.i0);
  MyTest.Free;
end;

Geändert von TiGü (23. Feb 2021 um 12:59 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 16:13 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