Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Record helper für statische Arrays (https://www.delphipraxis.net/203617-record-helper-fuer-statische-arrays.html)

Dennis07 5. Mär 2020 13:05

Delphi-Version: 10.2 Tokyo

Record helper für statische Arrays
 
Hallo Leute,
ich wollt mal fragen ob euch ein triftiger Grund einfällt, wieso ich für statische Arrays keine Helperklassen definieren kann.
Das geht ja sowohl bei dynamischen Arrays als auch bei Records und sogar bei kurzen Strings!
Mir fällt beim besten Willen kein Grund ein, warum das nicht auch bei statischen Arrays demnach gehen sollte.
Ist es einfach nur ein Compiler-Bug, oder spricht da eures Wissens nach irgendetwas gegen?

Danke!

freimatz 5. Mär 2020 13:22

AW: Record helper für statische Arrays
 
Der Grund dass es nicht geht liegt wohl daran, dass es nicht implementiert ist und das vielleicht weil bislang keiner einen Grund fand das zu wollen. Wozu brauchst du das denn?

himitsu 5. Mär 2020 13:56

AW: Record helper für statische Arrays
 
Klar, im Prinzip gäbe es keinen Grund, warum der Record-Helper nicht an einen statischen Array-Typen dran geht.
Ein statisches Array ist Verwaltungstechnisch nichts anderes, wie ein Record,
und für native Typen oder dynamische Arrays funktioniert der Record-Helper jedenfalls auch.

Delphi-Quellcode:
type
  TTest1 = Byte;
  TTest2 = array[0..10] of Byte;
  TTest3 = record x: array[0..10] of Byte end;
  TTest4 = record x: TTest2 end;

  TTest1Helper = record helper for TTest1 end; // RecordHelper für nativen Typen geht
  TTest2Helper = record helper for TTest2 end; // [dcc32 Fehler] E2474 Record-Typ erforderlich
  TTest3Helper = record helper for TTest3 end; // RecordHelper an Record geht natürlich
  TTest4Helper = record helper for TTest4 end; // und hier ebenfalls
Notfalls kann der Compiler hier auch einfach implizit einen Records drumrum legen.

Über einen Cast in den Record verschieben, oder direkt als Array-Record deklarieren.
Delphi-Quellcode:
type
  TTest = array[0..10] of Byte;
  TTestX = record x: TTest end;

  TTestHelper = record helper for TTestX
    procedure DoWhatever;
  end;

procedure TForm1.FormCreate(Sender: TObject);
var
  x: TTest;
begin
  TTestX(x).DoWhatever;
end;
Aber dann braucht man den Helper nicht unbedingt und kann es auch direkt in den Record reintun.
Delphi-Quellcode:
type
  TTest = array[0..10] of Byte;
  TTestX = record
    X: TTest
    procedure DoWhatever;
  end;

procedure TForm1.FormCreate(Sender: TObject);
var
  x: TTest;
begin
  TTestX(x).DoWhatever;
end;
Nun nochmal mit implizitem Cast versucht, aber Delphi möchte nicht die möglichen Casts durchprobieren.
Delphi-Quellcode:
type
  TTest = array[0..10] of Byte;
  TTestI = record
    X: TTest;
    class operator Implicit(Source: TTest): TTestI;
    procedure DoWhatever;
  end;

class operator TTestI.Implicit(Source: TTest): TTestI;
begin
  Result.X := Source;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  X: TTest;
begin
  X.DoWhatever; // [dcc32 Fehler] E2018 Record, Objekt oder Klassentyp erforderlich
end;

Ein Array-Helper wäre was, für statische Arrays. (und auch für dynamische Arrays, notfalls ohne die Möglichkeit der Längenänderung, also behandelt wie statisch)
Delphi-Quellcode:
type
  TTest = array[0..10] of Byte;

  TTestHelper = array helper for Byte
    procedure DoWhatever;
  end;
Für dynamische Arrays geht es ja.
Delphi-Quellcode:
type
  TTest = TArray<Byte>;

  TTestHelper = record helper for Test
    procedure DoWhatever;
  end;

  TTestHelper2 = record helper for TArray<Byte> // das geht zwar auch, aber die Klassenvervollständigung wunderschön ab
    procedure DoWhatever;                       // Messagebox: END erwartet, aber '<' gefunden in Klasse TTestHelper2.
  end;

Dennis07 5. Mär 2020 14:33

AW: Record helper für statische Arrays
 
Zunächst einmal danke für die Antworten.

Zitat:

Zitat von freimatz (Beitrag 1458979)
Der Grund dass es nicht geht liegt wohl daran, dass es nicht implementiert ist und das vielleicht weil bislang keiner einen Grund fand das zu wollen.

Naja, wieso braucht man denn einen Grund, bei statischen Arrays keine Ausnahme zu machen? Wenn man ein Feature implementiert, dann sollte es schon einen expliziten Grund geben, weswegen man es für einen bestimmten Use-Case nicht zur Verfügung stellt. Zumal der Mehraufwand hier wohl wirklich minimal gewesen wäre

Zitat:

Zitat von freimatz (Beitrag 1458979)
Wozu brauchst du das denn?

Naja, wozu mal Helper nunmal "braucht". Als Erweiterung für Typen, die man nicht ableiten will oder kann. Aus dem selben Grund, wieso es auch Helper für Strings, Integers, Chars, GUIDs, etc... gibt. Es macht Code nunmal erheblich schöner und übersichtlicher, wenn man anstelle globaler Prozeduren und Funktionen Record-bzw. Class-Helper deklariert.

Zitat:

Zitat von himitsu (Beitrag 1458982)
...

Jo, das wäre natürlich eine Möglichkeit. Nur leider Gottes kann man mit Records nicht das selbe machen, das man mit statischen Arrays machen kann. Hier liegt nämlich das Problem: Bräuchte ich nicht genau statische Arrays, würde ich sie ja auch hier nicht benutzen. Aber in sehr vielen Situationen verlangt der Compiler nun einmal einen nicht-initialisierten/-finalisierten Typen, und da kann man nunmal keine Records oder dynamischen Arrays nehmen. Nur einfache Typen, Zeiger oder Statische Arrays.
Trotzdem Danke für den gut formulierten Hinweis. ;-)

freimatz 5. Mär 2020 14:58

AW: Record helper für statische Arrays
 
"Zumal der Mehraufwand hier wohl wirklich minimal gewesen wäre" - das sagen meine Kunden auch immer :wink:
Ich kann mir vorstellen dass es doch etwas mehr Aufwand ist. Ein record hat per see schon mehrere unterschiedliche Elemente, da noch etwas hinzufügen ist einfacher als bei etwas, das nur aus lauter gleichen Elementen besteht. Aber das ist nur eine Vermutung, ich kenne die Internas nicht.

"Naja, wozu mal Helper nunmal "braucht". Als Erweiterung für Typen, die man nicht ableiten will oder kann." - zu kann fallen mir alle Typen aus der RTL, VCL u.a. ein. Statische arrays sind mit da noch nicht untergekommen.
Selber haben wir öffentliche statische arrays nur bei Vektoren und Matrizen. Das gilt bei uns auch schon veraltet, man sollte den Record nehmen der das kapselt. So hat das ja auch himitsu vorgeschlagen.
In anderen Fällen würde ich eh immer eine Klasse drum rum bauen.

himitsu 5. Mär 2020 14:59

AW: Record helper für statische Arrays
 
Zitat:

Zitat von Dennis07 (Beitrag 1458986)
Nur einfache Typen, Zeiger oder Statische Arrays.

Das triff aber auch auf Records zu.

Wobei es so bei statischen Arrays und Records davon abhängt, was für Typen drin sind.
Strings und Interfaces und schon werden dieses Records/Arrays auch initialisiert und finalisiert (bzw. sie müssen es, sonst Preng und/oder Speicherlecks)

@freimats: Delphi verwaltet Records wie ein Array mit der Länge 1 (entsprechend
Delphi-Quellcode:
array of record
bzw.
Delphi-Quellcode:
array[...] of record
),
was man in der System.pas gern seinen Augen antun kann.

Dennis07 5. Mär 2020 18:39

AW: Record helper für statische Arrays
 
Zitat:

Zitat von freimatz (Beitrag 1458990)
Ein record hat per see schon mehrere unterschiedliche Elemente, da noch etwas hinzufügen ist einfacher als bei etwas, das nur aus lauter gleichen Elementen besteht. Aber das ist nur eine Vermutung, ich kenne die Internas nicht.

Naja, aber erstens haben Strings, Zahlen und dynamische Arrays auch keine Member, und zweitens sind das ja keine "echten" Member, sondern nur globale Routinen mit einem entsprechenden Parameter als "Self". RTTI und vererbung gibt es bei Helpern ja gar nicht. Insofern bezweifle ich durchaus, dass es tatsächlich noch mal deutlich mehr Arbeit gewesen wäre, das zu implementieren. Mir erscheint es eher wie eine willkürliche Einschränkung zu sein, als einen echten technischen Hintergrund zu haben.

Zitat:

Zitat von freimatz (Beitrag 1458990)
zu kann fallen mir alle Typen aus der RTL, VCL u.a. ein. Statische arrays sind mit da noch nicht untergekommen.
Selber haben wir öffentliche statische arrays nur bei Vektoren und Matrizen. Das gilt bei uns auch schon veraltet, man sollte den Record nehmen der das kapselt. So hat das ja auch himitsu vorgeschlagen.
In anderen Fällen würde ich eh immer eine Klasse drum rum bauen.

Joa, könnt ihr ja machen wie ihr wollt. Aber manchmal nimmt man halt Arrays, weil Records halt auch ihre Nachteile haben. Besonders wenn es darum geht, dass Record-Felder ja als Eigenschaften und Parameter ja Readonly sind.

Zitat:

Zitat von himitsu (Beitrag 1458991)
Wobei es so bei statischen Arrays und Records davon abhängt, was für Typen drin sind.
Strings und Interfaces und schon werden dieses Records/Arrays auch initialisiert und finalisiert (bzw. sie müssen es, sonst Preng und/oder Speicherlecks)

Joa eben, deshalb bringt es ja nichts... :-D

himitsu 5. Mär 2020 21:29

AW: Record helper für statische Arrays
 
Vererbung gibt es bei Helpern.

Zum Glück, denn sonst wären Helper zu nichts zu gebrauchen, wenn man selber Typen erweitern will und dann mit den vordefinierten Helpern kollidiert.
Ich hoffe aber noch, dass der Entwickler irgendwann mal den gravierenden Bug behebt, wonach immer nur der letzte Helper nutzbar ist, denn Helper aus Fremdkomponenten können nicht voneinander erben, vor allem nicht firemübergreifend.

Uwe Raabe 5. Mär 2020 22:05

AW: Record helper für statische Arrays
 
Zitat:

Zitat von himitsu (Beitrag 1459017)
Vererbung gibt es bei Helpern.

Nur bei class helper for, nicht bei record helper for.

himitsu 5. Mär 2020 22:23

AW: Record helper für statische Arrays
 
Na das ist dann ja richtig doof.

Dennis07 6. Mär 2020 10:20

AW: Record helper für statische Arrays
 
Ich weiß im Augenblick nicht ganz, was ihr mit "Vererbung" hier meint. Denn Class Helper lassen sich ja nicht ableiten.

Neutral General 6. Mär 2020 10:25

AW: Record helper für statische Arrays
 
Es zählt immer nur 1 Helper. Wenn du 2 Helper für den gleichen Typen machst gilt immer nur der neuste (bzw. am "nächsten" deklarierte)

Uwe Raabe 6. Mär 2020 11:56

AW: Record helper für statische Arrays
 
Zitat:

Zitat von Dennis07 (Beitrag 1459039)
Ich weiß im Augenblick nicht ganz, was ihr mit "Vererbung" hier meint. Denn Class Helper lassen sich ja nicht ableiten.

Doch!

Hier zwei Beispiele:
Delphi-Quellcode:
program Project624;

{$APPTYPE CONSOLE}

uses
  FMX.Types3D;

type
  TMyContexHelper = class helper (TContextHelper) for TContext3D
  public
    procedure Hurz;
  end;

procedure TMyContexHelper.Hurz;
begin
end;

var
  context: TContext3D;
begin
  context.FillCube(NullPoint3D, NullPoint3D, 0, 0); // deklariert in TContextHelper
  context.Hurz;
end.
Delphi-Quellcode:
program Project639;

{$APPTYPE CONSOLE}

uses
  System.Net.HttpClient;

type
  TMyHelper = class helper (THTTPClientHelper) for THTTPClient
  public
    procedure Hurz;
  end;

procedure TMyHelper.Hurz;
begin
end;

var
  Client: THTTPClient;
begin
  client.UseDefaultCredentials := True; // deklariert in THTTPClientHelper
  client.Hurz;
end.

Dennis07 6. Mär 2020 15:08

AW: Record helper für statische Arrays
 
Oh, wow! Okay, danke!
Hätte die Klammern nicht hinter dem helper sondern dem Klass oder dem Typen vermutet. :cyclops:

Danke!

Rollo62 7. Mär 2020 07:42

AW: Record helper für statische Arrays
 
Hallo Uwe,

dankesehr, das hatte ich schon lange als "geht nicht" verbucht :thumb:

himitsu 10. Mär 2020 14:55

AW: Record helper für statische Arrays
 
"class helper" und "record helper" sind quasi ein Wort, womit man sich erklären kann, warum die Vererbung dort rein muß.

Dennis07 10. Mär 2020 18:22

AW: Record helper für statische Arrays
 
Zitat:

Zitat von himitsu (Beitrag 1459421)
"class helper" und "record helper" sind quasi ein Wort, womit man sich erklären kann, warum die Vererbung dort rein muß.

Wenn Delphi da mal so Konsistent wäre...

Es heißt
Delphi-Quellcode:
class abstract
, aber
Delphi-Quellcode:
packed record
. Wobei man ja nicht einmal aus "Helper" einen reservierten Begriff im Editor gemacht hat, weshalb es halt immer noch "falsch" aussieht, so etwas geschrieben zu haben.

Uwe Raabe 10. Mär 2020 18:58

AW: Record helper für statische Arrays
 
Zitat:

Zitat von Dennis07 (Beitrag 1459435)
Es heißt
Delphi-Quellcode:
class abstract
, aber
Delphi-Quellcode:
packed record
.

Obwohl der Sinn eher fraglich ist, heißt es auch
Delphi-Quellcode:
packed class
...

Dennis07 10. Mär 2020 19:02

AW: Record helper für statische Arrays
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1459436)
Obwohl der Sinn eher fraglich ist, heißt es auch
Delphi-Quellcode:
packed class
...

Jo, auf
Delphi-Quellcode:
packed class
bzw.
Delphi-Quellcode:
packed array
bin ich deshalb auch nicht eingegangen.

TiGü 11. Mär 2020 10:23

AW: Record helper für statische Arrays
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1459047)
Doch!

Hier zwei Beispiele:

Delphi-Quellcode:
program Project639;

{$APPTYPE CONSOLE}

uses
  System.Net.HttpClient;

type
  TMyHelper = class helper (THTTPClientHelper) for THTTPClient
  public
    procedure Hurz;
  end;

procedure TMyHelper.Hurz;
begin
end;

var
  Client: THTTPClient;
begin
  client.UseDefaultCredentials := True; // deklariert in THTTPClientHelper
  client.Hurz;
end.

Ach guck, wieder was gelernt! :shock:

Dann kann es doch nicht so schwierig sein, dem Kompiler beizubringen, das auch für record helper zu machen.
Bei den ganzen aufgekauften Firmen von Idera müssen doch mal ein, zwei Leute dabei sein, die die Delphi-Kompiler diesbezüglich erweitern können.
Aber ich schweife ab, tut mir leid!

Jost Riedel 25. Mär 2020 18:55

AW: Record helper für statische Arrays
 
Wenn man allerdings das statische Array in einen record einhüllt, dann braucht keinen record helper mehr:

type
ByteArray10 = record
x: array[0..10] of Byte;
procedure DoWhatever;
end;

procedure ByteArray10.DoWhatever;
begin
end;

Es ist schon spaßig: Für records braucht man keine "record helper", einen helper für einen enumerierten Typ, ein Set, usw. "record helper" zu nennen ist schon etwas irreführend.

himitsu 25. Mär 2020 20:33

AW: Record helper für statische Arrays
 
Jupp, siehe Antwort #3.
Zitat:

Zitat von himitsu (Beitrag 1458982)
Aber dann braucht man den Helper nicht unbedingt und kann es auch direkt in den Record reintun.

Wenn man einfach nur den "grundlegenden" Unterschied von Record und Klasse nimmt, dann wäre die Sache etwas klarer.
* CLASS für Klassen, also alles mit impliziten Pointern
* RECORD für alle Records und native Typen ohne Pointer, wo die Daten direkt in der Variable stecken (ja, auch der Pointer selbst ist ein nativer Typ)

Wobei hier der STRING und dynamische Arrays demnach ja eigentlich einen Class-Helper benötigen würden.
Dann vielleicht CLASS Helper eben für Klassen und Interfaces, welche mit einem Contructor erstellt werden müssen, und RECORD für alles Andere.

Gut, Helper ist Helper und man hätte eigentlich keine verwirrend unterschiedlichen Namen benötigt.

himitsu 5. Nov 2022 14:08

AW: Record helper für statische Arrays
 
Schade, geht im 11.2 auch immernoch nicht, dabei wollte ich grade :cry:


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