Frage

Für jedes Setter einer Klasse Ich habe einige Ereignislogik (OnChanging, OnChanged) zu implementieren:

procedure TBlock.SetWeightIn(const Value: Double);
var OldValue: Double;
begin
  OldValue := FWeightIn;
  DoOnChanging(OldValue, Value);
  FWeightIn := Value;
  DoOnChanged(OldValue, Value);
end;

procedure TBlock.SetWeightOut(const Value: Double);
var OldValue: Double;
begin
  OldValue := FWeightOut;
  DoOnChanging(OldValue, Value);
  FWeightOut := Value;
  DoOnChanged(OldValue, Value);
end;

Können Sie sich bitte einen Weg vorschlagen, dies zu implementieren, ohne für jeden Setter all diese Zeilen duplizieren?

War es hilfreich?

Lösung

Versuchen Sie folgendes:

procedure TBlock.SetField(var Field: Double; const Value: Double);
var
    OldValue: Double;
begin
    OldValue := Field;
    DoOnChanging(OldValue, Value);
    Field := Value;
    DoOnChanged(OldValue, Value);
end;

procedure TBlock.SetWeightIn(const Value: Double);
begin
    SetField(FWeightIn, Value);
end;

procedure TBlock.SetWeightOut(const Value: Double);
begin
    SetField(FWeightOut, Value);
end;

Andere Tipps

Delphi unterstützt indiziert Eigenschaften . Mehrere Eigenschaften können durch einen Ordinalindex einen einzigen Getter oder Setter, differenziert teilen:

type
  TWeightType = (wtIn, wtOut);
  TBlock = class
  private
    procedure SetWeight(Index: TWeightType; const Value: Double);
    function GetWeight(Index: TWeightType): Double;
  public
    property InWeight: Double index wtIn read GetWeight write SetWeight;
    property OutWeight: Double index wtOut read GetWeight write SetWeight;
  end;

Sie können dies kombinieren mit Cobus Antwort diese zu bekommen:

procedure TBlock.SetWeight(Index: TWeightType; const Value: Double);
begin
  case Index of
    wtIn: SetField(FWeightIn, Value);
    wtOut: SetField(FWeightOut, Value);
  end;
end;

Dies könnte Ihnen Ideen für andere Möglichkeiten, wie Sie auf Ihre Felder durch einen Index, anstelle von zwei völlig getrennte Felder für solche verwandten Werte beziehen können.

Sie könnten eine zusätzliche Methode hinzufügen. So etwas wie:

procedure TBlock.setValue(const Value : Double; Location : PDouble);
var
  OldValue : Double;
begin
   OldValue:=Location^;
   DoOnChanging(OldValue,Value);
   Location^:=Value;
   DOnChanged(OldValue, Value);
end;

procedure TBlock.setWeightOut(const Value : Double);
begin
  setValue(value, @FWeightOut);
end;

Ich habe nicht kompiliert / getestet, obwohl Sie den Code. Die Idee ist, eine allgemeine Setter-Methode zu haben, die mit einem Zeiger auf den Ort funktioniert. Die spezialisierten Versionen rufen Sie einfach die gerneral Methode mit der Adresse der Variablen festgelegt werden. Sie haben je nach Art der Variable einen Typen von allgemeiner Setter-Methode haben (Doppel, integer, ...) aber. Sie könnten es ändern auf Zeiger und Länge einer Variablen arbeiten mit allen Arten zu arbeiten -. Ihre Entscheidung, ob es lohnt sich

Wenn Prozedur / Funktion der Parameter sind die gleichen und Code zwischen Anfang und Ende sind die gleichen, dann können Sie nur verwenden,

procedure SetWeightValue(const Value: Double);
var OldValue: Double;
begin
  OldValue := FWeightIn;
  DoOnChanging(OldValue, Value);
  FWeightIn := Value;
  DoOnChanged(OldValue, Value);
end;

Das ist es ...

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