Wiederholte Setter-Logik in Delphi
-
19-09-2019 - |
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?
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 ...