2010-04-13 6 views
2
Data.XX.NewValue := Data.XX.SavedValue; 
    Data.XX.OldValue := Data.XX.SavedValue; 

Je dois faire ce qui précède un grand nombre de fois, où XX représente la valeur de la classe. Prétendant il y avait 3 éléments dans la liste: Tim, Bob, Steve. Est-il possible de faire ce qui précède pour les trois personnes sans taper le code ci-dessus trois fois?Répéter la procédure pour chaque élément de la classe

(données est une classe contenant un certain nombre d'objets, chaque type TList, qui contiennent OldValue, NewValue et savedValue)

+0

Sory ... Je ne comprends pas. Pouvez-vous m'expliquer pourquoi une boucle classique n'est pas suffisante pour cela? Quelque chose comme pour I: = 0 à data.count ne commencer données [I] .NewValue: = données [I] .SavedValue; Données [I] .OldValue: = Données [I] .SavedValue; fin; Cordialement. – jachguate

Répondre

4

ce que je ferais si je devais faire quelque chose comme cela est mis un plus TList sur Données, qui contient une liste de tous les objets. Remplissez-le dans le constructeur, puis lorsque vous devez faire quelque chose comme ça, utilisez une boucle pour appliquer la même opération de base à chaque élément de la liste.

-3

Je ferais attention ici. Je sais que la tentation sera d'utiliser une interface et une réflexion communes, ou une autre automatisation plus flexible et, franchement, plus amusante à écrire. Evite cette tentation. Il n'y a rien de mal à répertorier tous les éléments de la liste en fonction de votre modèle. Les modèles sont bons, et le code sera lisible, facile à exécuter, et facile à modifier toute propriété individuelle qui ne correspond pas au modèle.

La façon la plus simple d'éviter de taper tout est d'utiliser notre vieil ami Excel. Mettez toutes vos propriétés dans la colonne A, puis utilisez cette formule dans la colonne B:

= CONCATENATE("Data.", A1, ".NewValue := Data.", A1, ".SavedValue;", CHAR(10), "Data.", A1, ".OldValue := Data.", A1, ".SavedValue;", CHAR(10)) 
+0

Alors que générer du code dans Excel est une bonne chose à avoir dans votre boîte à outils, je suis en désaccord avec cette approche. S'il a 1000 éléments à traiter, vous allez générer 1000 lignes de code répétitif. Cependant, pour des choses comme générer des instructions pour manipuler des tables et des structures de base de données (créer, sélectionner, insérer, analyser, etc.), cette technique fonctionne très bien. –

+3

Difficile de penser à une réponse plus non-Delphi-ish. ;-) –

+0

Vous devez examiner toutes les approches et peser le pour et le contre. Le fait que cette approche génère de nombreuses lignes de code et soit répétitive n'est pas en soi un inconvénient en termes de performance et de maintenance future.Puisque seulement une personne a suggéré une solution, et une viable à cela, nous devrions comparer les inconvénients. Quel genre de code allons-nous écrire pour la nouvelle propriété? N'aura-t-il pas à lister toutes les propriétés de façon répétitive? Maintenant, nous avons encore 1000 lignes de code répétitif, mais nous avons aussi un tout nouvel élément de données pour créer, maintenir et utiliser la mémoire. – cortijon

0

Peut-être que je ne comprends pas ce ok, mais ... Voici où brille Objet. Vous définissez une procédure pour la classe, puis vous appliquez pour toute instance que vous créez.

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; 

Hope this aide Daniel

0

A en juger par this post et this post, je suggère ce qui suit:

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. 

Maintenant, vous pouvez écrire ce genre de code:

  //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); 

Si vous avez besoin de manipulations plus complexes sur le tableau, ce serait une bonne idée de le placer dans une classe - remplacez les champs que vous avez écrits avec seulement sur efield de type TDataArray - et écrivez les fonctions pour manipuler les données en tant que méthodes de cette classe.

Questions connexes