Frage

Also, was wird die bevorzugte Art und Weise der Initialisierung Datensätze sein?

Mit einer 'Fabrik-Funktion':

TMyRecord = record
  valueX: integer;
  valueY: integer;
end;

function MyRecord(const AValueX, AValueY: integer): TMyRecord;
begin
  result.valueX := AValueX;
  result.valueY := AValueY;
end;

var
  myrec: TMyRecord;
begin
  myrec := MyRecord(1, 2);
end;

oder ein Konstruktor:

TMyRecord = record
  valueX: integer;
  valueY: integer;
  constructor Create(const AValueX, AValueY: integer);
end;

constructor TMyRecord.Create(const AValueX, AValueY: integer);
begin
  self.valueX := AValueX;
  self.valueY := AValueY;
end;

var
  myrec: TMyRecord;
begin
  myrec := TMyRecord.Create(1, 2);
end;

Ich glaube, dass die Konstruktor Dinge mehr verkapselt, aber es macht es leicht zu Verwechslungen kommen, wenn der Code zu lesen. Es macht es wie eine Klasse suchen, die einen Anruf kostenlos fehlen. Es ist auch mehr zu geben ...

Warum würden Sie einen über den anderen vorziehen?

War es hilfreich?

Lösung

Ich ziehe es Klassen, aber wenn ich Datensätze verwenden, wie ich sie so ähnlich wie möglich wie Klassen zu behandeln. So verwende ich den Rekord-Konstruktor.

Aber es ist ein ärgerlicher Fehler mit Aufzeichnungen und Einheiten. Wenn eine Funktion eine Aufzeichnung (mit Methoden) gibt, erzeugt es einen internen Fehler, wenn Sie diese Methoden zugreifen möchten. Sie können dies umgehen, indem es auf eine andere Variable zuweisen:

type 
  TMyRec = record
    ..
    procedure X;
  end;


function GetRec: TMyRec;



procedure Test;
var
  r1, r2 : TMyRec;
begin
  r1 := GetRec;
  r1.X; // internal error
  r2 := r1;
  r2.X; // No internal error;

Andere Tipps

würde ich "Factory-Methode" wie

bevorzugen
  function TMyRecord.CreateRec(const AValueX, AValueY: integer): TMyRecord;

Separate Fabrik Funktion Lecks Verkapselung und Rekord Konstrukteuren nur IMHO verwechseln.

In einem Delphi-Projekt, das ich geschaffen, habe ich Aufzeichnungen anstelle von Klassen, um die Menge an Overhead auf einer Liste zu reduzieren. Ich würde mehrere hundert Datensätze in einem dynamischen Array haben, damit ich zwei Datensätze erstellt. Der erste Datensatz war für das Element selbst. Die Felder wurden als privat (ja, können Sie private Nutzung / mit Aufzeichnungen geschützt) aufgelöst und schreibgeschützte Objekte, die den öffentlichen Bereich. Ein weiterer Konstruktor wurde auch die Aufzeichnung in der richtigen Art und Weise zu initialisieren hinzugefügt. Dieses Setup erlaubt mir den Inhalt dieser Datensatz von anderen Entwicklern zu schützen. Der zweite Datensatz war nur ein Wrapper um ein dynamisches Array des vorherigen Datensatztypen. Das Array wäre privat und ich fügte Methoden zu erhalten, hinzufügen und löschen Einträge in dieser Liste. Als Ergebnis wird die gesamte Liste geschützt gegen falschen Gebrauch von anderen Entwicklern und hat auch viel weniger Overhead als eine normale TList / TObjectList Lösung.

Halten Sie daran, dass die Datensätze sind nicht Klassen. Sie können nicht Konstrukteuren und anderen Methoden erben. Sie haben weniger Funktionalität als echte Klassen in WIN32-Umgebungen. In .NET, sind sie nur wieder Klassen gefördert. Und es ist nicht sehr nützlich, um einen Konstruktor zu verwenden hinzufügen, wenn Entwickler leicht, den Inhalt jeder ändern können und jedes Feld in der Aufzeichnung. Sie sollten Konstrukteure verwenden, um stattdessen die Felder zu schützen.

Ich mache in der Regel nicht Konstrukteuren für Datensätze. Es ist nicht kompatibel mit allen Versionen (und FPC). Außerdem ist typischerweise nur in einem Ort, der sie verwendet und oft eine FillChar ist genug.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top