Wie mache ich eine TStringList global in Lazarus?

1 Antwort

Vom Fragesteller als hilfreich ausgezeichnet

Im besten Fall gar nicht, denn umso globaler der Zugriff auf eine Variable ist, umso mehr potenzielle Fehlerquellen öffnen sich. Es wird schwerer nachzuvollziehen, wer wann den Zustand der Variable ändert.

Innerhalb einer Klasse kannst du ein Feld anlegen, welches beim Erstellen eines Objekts dieser Klasse mit kreiert wird und so lange im Speicher verweilt, bis man das Objekt wieder abräumt.

Ein Beispiel:

type
  TApple = class
  private
    _weight: Integer;
  public
    property Weight: Integer read _weight write _weight;

    procedure TApple.PrintWeight;
  end;

  procedure TApple.PrintWeight;
  begin
    WriteLn(Weight);
  end;

Hier wird ein neues Feld namens _weight erstellt (der Unterstrich ist nur ein Stilmittel, um zu kennzeichnen, dass diese Variable ein privates Feld darstellt). Dieses ist nur innerhalb der Klasse sichtbar (private). Also auch innerhalb jeder objektgebundenen Methode (wie bspw. PrintWeight).

Zusätzlich habe ich ein Property definiert, welches fortan den Zugriff auf dieses Feld verwalten soll. Das heißt, wenn du das Feld lesen/ändern möchtest, nimmst du stattdessen das Property.

Beispiel:

var
  apple: TApple;
  appleWeight: Integer;
begin
  apple := TApple.Create;
  apple.Weight := 5; // set
  appleWeight := apple.Weight; // get
  apple.Free;
end;

Der Vorteil durch das Property ist, dass du eine Entkopplung von Feld und Aufrufer hast. Man könnte das Property nun noch in seiner Definition verändern und bspw. Methoden dazwischenschalten, die bei Zugriff aufgerufen werden und zusätzliche Logik implementieren.

Beispiel:

// ...

private
  // ...
  function GetWeight: Integer;
  procedure SetWeight(weight: Integer);
public
  property Weight: Integer read GetWeight write SetWeight;
end;

function TApple.GetWeight: Integer;
begin
  if weight < 0 then
    begin
      Result := 0;
    end
  else
    begin
      Result := _weight;
    end;
end;

procedure TApple.SetWeight(weight: Integer);
begin
  if weight > 0 then
    begin
      Result := _weight;
    end;
end;        

Wenn du nun dein Feld (bzw. dessen Wert) an ein anderes Objekt weiterreichen möchtest, nutze Methoden (mit Parametern/Rückgabewert) oder Properties dafür. Reiche dein Objekt nur an die Programmelemente weiter, die tatsächlich Zugriff darauf brauchen.

Beispiel:

var
  apple1, apple2: TApple;
begin
  apple1 := TApple.Create;
  apple1.Weight := 5;
  apple2 := TApple.Create;
  apple2.Weight := apple1.Weight; // pass value

  apple1.Free;
  apple2.Free;
end;