Delphi中重复的setter逻辑

时间:2009-07-23 07:10:31

标签: delphi pascal delphi-2006

对于每个类的setter,我必须实现一些事件逻辑(OnChanging,OnChanged):

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;

请您建议一种方法来实现这一点,而不是为每个setter重复所有这些行?

4 个答案:

答案 0 :(得分:13)

试试这个:

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;

答案 1 :(得分:7)

Delphi支持索引属性。多个属性可以共享一个getter或setter,由序数索引区分:

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;

您可以将其与Cobus's answer结合使用以获取此信息:

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

这可能会为您提供其他方式的建议,您可以通过索引引用字段,而不是为这些相关值设置两个完全独立的字段。

答案 2 :(得分:0)

您可以添加其他方法。类似的东西:

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;

我没有编译/测试代码。我们的想法是使用一个通用的setter方法,该方法使用指向该位置的指针。专用版本只需要设置变量的地址就可以调用gerneral方法。 每种类型的变量(double,integer,...)都必须有一种通用的setter方法。您可以修改它以处理指针和变量的长度以适用于所有类型 - 您的决定是否值得。

答案 3 :(得分:0)

如果过程/函数的参数相同,并且开始和结束之间的代码相同,那么您可以使用

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

就是这样......