Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 对类中的每个项重复此过程_Delphi_Class_Delphi 7_Repeat - Fatal编程技术网

Delphi 对类中的每个项重复此过程

Delphi 对类中的每个项重复此过程,delphi,class,delphi-7,repeat,Delphi,Class,Delphi 7,Repeat,我需要多次执行上述操作,其中XX表示类中的值。假装名单上有三项:蒂姆、鲍勃、史蒂夫。有没有任何方法可以在不输入上述代码三次的情况下为所有三个人执行上述操作 (Data是一个包含许多对象的类,每种类型为TList,其中包含OldValue、NewValue和SavedValue)如果必须这样做,我会在数据上再放置一个TList,其中包含所有对象的列表。将其填入构造函数,然后当您必须执行类似操作时,使用循环将相同的基本操作应用于列表中的每个项。我在这里会小心。我知道诱惑将是使用一个通用的接口和反射,

我需要多次执行上述操作,其中XX表示类中的值。假装名单上有三项:蒂姆、鲍勃、史蒂夫。有没有任何方法可以在不输入上述代码三次的情况下为所有三个人执行上述操作


(Data是一个包含许多对象的类,每种类型为TList,其中包含OldValue、NewValue和SavedValue)

如果必须这样做,我会在数据上再放置一个TList,其中包含所有对象的列表。将其填入构造函数,然后当您必须执行类似操作时,使用循环将相同的基本操作应用于列表中的每个项。

我在这里会小心。我知道诱惑将是使用一个通用的接口和反射,或者其他更灵活、更有趣的自动化。避免这种诱惑。根据您的模式列出列表中的每一项并没有错。模式很好,代码可读性强,易于执行,并且易于修改任何不符合模式的单个属性

避免将所有内容都打印出来的低技术方法是使用我们的老朋友Excel。将所有属性放在A列中,然后在B列中使用此公式:

  Data.XX.NewValue := Data.XX.SavedValue;
  Data.XX.OldValue := Data.XX.SavedValue;

也许我不明白,好吧,但是。。。 这就是面向对象的优势所在。为类定义一个过程,然后应用于创建的任何实例

=  CONCATENATE("Data.", A1, ".NewValue := Data.", A1, ".SavedValue;", CHAR(10), "Data.", A1, ".OldValue := Data.", A1, ".SavedValue;", CHAR(10))
希望这有帮助 丹尼尔

根据和判断,我建议如下:

TMyPropValue = class(TObject)
private
  FNewValue: double;   
  FOldValue: double;
  procedure SetValue(AValue: double);
public
  procedure RestoreOldValue;
  propety NewValue: double read FNewValue write SetValue;   // Raed/write property (write using a procedure)
  property OldValue: double read FOldValue;   // Read only property
end;

TMyClass = class(TObject)
private
  FProp1: TMyPropValue;
  FProp2: TMyPropValue;
public
  procedure RestoreValues;
end;

//....

var
  MyObj1: TMyClass;
  MyObj2: TMyclass;

procedure TMyPropValue.SetValue(AValue: double);
begin
  FOldValue := FNewValue;
  FNewValue := AValue;  
end;

// Restore the Old value of this Prop
procedure TMyPropValue.RestoreOldValue;
begin
  FNewValue := FOldValue;  
end;

// Restore ald the Values of the class
procedure TMyClass.RestoreValues;
begin
  FProp1.RestoreOldValue;
  FProp2.RestoreOldValue;
end;
// -----------

// Creating and populating a couple of objects (instances)
procedure XXX;
begin
  MyObj1 := TMyClass.Create;
  MyObj1.Prop1.NewValue := 10.25:
  MyObj1.Prop2.NewValue := 99.10:

  MyObj2 := TMyClass.Create;
  MyObj2.Prop1.NewValue := 75.25:
  MyObj2.Prop2.NewValue := 60.30:
end;

// Changing values, the class internaly will save the OldValue
procedure yyyy;
begin
  MyObj1.Prop1.NewValue := 85.26:
  MyObj1.Prop2.NewValue := 61.20:

  MyObj2.Prop1.NewValue := 99.20:
  MyObj2.Prop2.NewValue := 55.23:
end;

// Using a procedure from the class
procedure zzzz;
begin
  MyObj1.RestoreValues;
  MyObj2.RestoreValues;
end;
现在您可以编写这种代码:

unit MyAssignment;

interface

  type
    TValueKind = ( EconomicGrowth,
                   Inflation,
                   Unemployment,
                   CurrentAccountPosition,
                   AggregateSupply,
                   AggregateDemand,
                   ADGovernmentSpending,
                   ADConsumption,
                   ADInvestment,
                   ADNetExports,
                   OverallTaxation,
                   GovernmentSpending,
                   InterestRates,
                   IncomeTax,
                   Benefits,
                   TrainingEducationSpending );

        TValue = record
          NewValue,
          OldValue,
          SavedValue : Double;

          procedure SetValue( aVal : Double );
          procedure SaveValue();
          procedure RestoreValue();
        end;

        TDataArray = array [TValueKind] of TValue;

        var
          Data : TDataArray;

implementation

    {TValue}

  procedure TValue.SetValue( aVal : Double );
  begin
    OldValue := NewValue;
    NewValue := aVal;
  end;

  procedure TValue.SaveValue;
  begin
    SavedValue := NewValue;
  end;

  procedure TValue.RestoreValue;
  begin
    NewValue := SavedValue;
    OldValue := SavedValue;
  end;


end.

如果您需要对数组进行更复杂的操作,最好将其放入一个类中—替换仅在TDataArray类型的efield上编写的字段—并编写函数以将数据作为该类的方法进行操作。

在Excel中生成代码时,工具箱中最好有,我不同意这种做法。如果他有1000个元素要处理,你将生成1000行重复的代码。然而,对于像生成语句来操作数据库表和结构(创建、选择、插入、解析等)这样的事情,这种技术非常有效。很难想出一个更非德尔菲式的答案。;-)你必须检查所有方法,权衡利弊。这种方法会生成许多行代码,并且是重复的,这一事实本身并不是性能和未来维护的缺点。因为只有一个人提出了一个解决方案,而且是可行的,所以我们应该比较缺点。我们将为新属性编写什么样的代码?难道它不需要自己重复列出所有属性吗?现在我们仍然有1000行重复代码,但我们也有一个全新的数据元素来创建、维护和占用内存。我想不出有哪种情况下1000行重复代码(我指的是代码而不是数据库查询等)实际上是好代码。我不敢相信你真的把这个选择(那不是一个)考虑进去了…对不起。。。我不明白。你能给我解释一下为什么经典的for循环不足以解决这个问题吗?类似于I:=0到数据。计数确实开始于数据[I]。NewValue:=Data[I]。SavedValue;数据[I]。旧值:=数据[I]。保存的值;结束;亲切的问候。
            //accessing the values :
            // Data[XX] instead of Data.XX

            //examples :
          ShowMessage(FloatToStr(Data[Inflation].SavedValue));
          Data[AgregateSupply].SetValue( 10.0 );
          Data[Benefits].SaveValue;

          //writing loops :
        procedure RestoreValues( var aData : TDataArray ); //the "var" keyword is important here : google "arguments by value" "arguments by reference"
          var
            lKind : TValueKind;
        begin
          for lKind := Low(TValueKind) to High(TValueKind) do
            aData[lKind].RestoreValue;
        end;

        procedure SaveValues( var aData : TDataArray );
          var
            lKind : TValueKind;
        begin
          for lKind := Low(TValueKind) to High(TValueKind) do
            aData[lKind].RestoreValue;
        end;

          //calling these functions :
        SaveValues( Data );
        RestoreValues( Data );