9

对于一个类的每个设置器,我必须实现一些事件逻辑(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

4 回答 4

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;
于 2009-07-23T07:41:24.087 回答
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 的答案结合起来得到:

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

这可能会为您提供其他方法的想法,您可以通过索引引用您的字段,而不是为此类相关值使用两个完全独立的字段。

于 2009-07-23T07:48:47.270 回答
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 方法,它与指向该位置的指针一起工作。专用版本只是调用带有要设置的变量地址的通用方法。但是,对于每种类型的变量(双精度、整数、...),您必须拥有一种通用的 setter 方法。您可以修改它以处理指针和变量的长度以适用于所有类型 - 您的决定是否值得。

于 2009-07-23T07:23:04.843 回答
0

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

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

就是这样...

于 2009-09-12T08:08:11.490 回答