Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Initialisierung von Records (https://www.delphipraxis.net/136199-initialisierung-von-records.html)

Zwoetzen 25. Jun 2009 12:10


Initialisierung von Records
 
Hi DP'ler,

Ist es möglich, bei der Deklaration von Records ein Initialisierungswert mit anzugeben?

Ich habe ein Record, nehmen wir beispielsweise
Delphi-Quellcode:
type TMyRecord = record
  ID: Integer;
  Name: String;
end;
Wenn ich nun eine Variable von diesem Typ anlege
Delphi-Quellcode:
var MyRecord: TMyRecord;
so hätte ich es gerne, dass der Name bereits mit einem Wert (beispielsweise 'Invalid' oder 'Empty') initialisiert wird. Ist das irgendwie möglich? (Nen Create wie bei Klassen gibt es ja nicht, wo man die Werte initialisieren könnte).


Danke für Antworten im Vorraus,

MfG Zwoetzen

Muetze1 25. Jun 2009 12:16

Re: Initialisierung von Records
 
Zitat:

Zitat von Zwoetzen
(Nen Create wie bei Klassen gibt es ja nicht, wo man die Werte initialisieren könnte).

Klar, bei deinem Delphi schon...

http://edn.embarcadero.com/article/34324

Zwoetzen 25. Jun 2009 12:25

Re: Initialisierung von Records
 
Ja, aber nur mit mindestens einem Parameter. (Sonst Fehler: "Parameterlose Konstruktoren sind für Record-Typen nicht zulässig"). (Hab mich an der Stelle wohl etwas falsch ausgedürckt...)

Ich würde es aber bevorzugen, wenn es "von außen" nicht anders aussehen würde wie sonst, und trotzdem die Initialisierung stattfindet ;)
Quasi sowas wie:
Delphi-Quellcode:
procedure moep;
var MyRecord: TMyRecord;
begin
  ShowMessage(MyRecord.Name); // Zeigt direkt 'Invalid' an
end;

gammatester 25. Jun 2009 13:37

Re: Initialisierung von Records
 
Delphi-Quellcode:
const
  Myrecord: TMyrecord = (ID:42; Name:'Invalid');

stoxx 26. Jun 2009 04:10

Re: Initialisierung von Records
 
wir nehmen immer eine procedure "Clear"
da ist dann alles "Null" :-)


Delphi-Quellcode:
procedure TMyRecord.Clear;
begin
    ZeroMemory(@self,SizeOf(TMyRecord));
end;

alzaimar 26. Jun 2009 05:44

Re: Initialisierung von Records
 
Hier gab es vor Kurzem eine Diskussion über das Für und Wider von implizit aufgerufenen Record-Konstruktoren. Ich war der Ansicht, das das keine gute Idee sei, denn so wäre die Initialisierung des Records unsichtbar. Andere Variablen werden auch nicht implizit initialisiert, und in modernen Programmiersprachen ist das Fehlen einer initialen Zuweisung ein Fehler, den der Compiler schon anmeckert.

Was spricht dagegen, deinen Record explizit über einen Konstruktor, oder eine Prozedur ("Initialize" wäre hier besser als "Clear") aufzurufen? Dann sieht man sofort, das der Record mit Vorgabewerten belegt wird.

Zwoetzen 26. Jun 2009 10:21

Re: Initialisierung von Records
 
Hmm, hab mir das ganze nochmal durch den Kopf gehen lassen, und denke nun auch, dass eine explizite Initialisierung über eine Methode [Heißt das bei Records eigentlich auch Methode, oder Prozedur/Funktion?] wohl der bessere Weg ist.
Trotzdem danke für eure Antworten, das mit dem const bei Records war zB auch neu für mich. Wieder was gelernt :mrgreen:

stoxx 26. Jun 2009 13:56

Re: Initialisierung von Records
 
Zitat:

Zitat von alzaimar
Was spricht dagegen, deinen Record explizit über einen Konstruktor, oder eine Prozedur ("Initialize" wäre hier besser als "Clear") aufzurufen? Dann sieht man sofort, das der Record mit Vorgabewerten belegt wird.

Initialize ist in dem Fall unsauber, eine andere Anwendung benötigt vielleicht eine ganze andere Initialisation?


"InitializeDefaultValues"
"InitializeSampleValues"

könnte schon eher brauchbar sein.

eine "initialisation" legt nur die "Struktur" an .. oder Initialisiert das Objekt oder Record mit übergebenen Parametern (einer Optionklasse)
oder ähnlichem ..

daher besser eine explizite Zuweisung der Werte, die man letztendlich reinschreiben möchte

myrecord.Name := 'Heinz';


sooo

alzaimar 26. Jun 2009 16:25

Re: Initialisierung von Records
 
Oh, jetzt wirds theoretisch: Ein Record repräsentiert einen abstrakten Datentyp. Die Menge der einzelnen Recordfelder repräsentiert seinen Gesamtzustand. Beispiel: Der abstrakte Datentyp sei 'TPerson', seine Recordfelder 'Name', 'Geburtsdatum', 'Geschlecht'.

Um dieseen Datentyp zu initialisieren, muss ich seinen Feldern Initialwerte zuweisen. Das muss ich wohldefiniert und immer gleich machen, denn es gilt (z.B.)
Code:
TKunde.IstImInitialzustand <==> Name=leer, Geburtsdatum=leer, Geschlecht=Unspezifiziert.
Das hat zunächst gar nichts mit 'Nullen' zu tun. Ich kann es so drehen, das ich mit einem FillChar(...,0) einen definierten Initialzustand herstelle, aber das schränkt mich unnötig ein.

Ich kann auch jedesmal ein explizite Zuweisung der einzelnen Felder auskodieren, aber das garantiert mir nicht, das zwei 'Instanzen' eines Kunden wirklich identisch initialisiert wurden.

Ich sollte also eine Initial/Clear-Methode für den Record implementieren, der mir meinen expliziten, eindeutigen und wohldefinierten Grundzustand herstellt. Ich würde diese Methode in Anlehnung an den Initialzustand eben 'Initialize' nennen, aber ich denke, 'Clear' geht auch, weil wir ja die Instanz auf einen Grundzustand setzen (Wir 'nullen' ihn im logischen Sinn).

Deinem Einwand, das das "Initialize" zu allgemein gültig wäre, muss ich partiell widersprechen. Und zwar partiell, weil wir -denke ich- unterschiedliche Ansätze verfolgen: Für mich gibt es im Kontext eines abstrakten Datentyps nur einen definierten Grundzustand, schließlich bilde ich u.U. noch eine (totale) Ordnung, Reflexion usw. über Operatoren ab. Und hier ist es unbedingt notwendig, eine eindeutige Definition der 'Null' zu haben.


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