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

Мне нужно сделать это много раз, где XX представляет значение в классе. Притворяясь, в списке было 3 пункта: Тим, Боб, Стив. Есть ли способ сделать выше для всех трех человек, не набрав вышеуказанный код три раза?Процедура повторения для каждого предмета в классе

(Data представляет собой класс, содержащий ряд объектов, каждый тип TList, которые содержат OldValue, NEWVALUE и SavedValue)

+0

Sory ... Я не понимаю. Можете ли вы объяснить мне, почему для этого недостаточно классического цикла? Что-то вроде для I: = 0 до Data.Count делать начинают данные [I] .NewValue: = Data [I] .SavedValue; Данные [I] .OldValue: = Данные [I] .SavedValue; конец; С наилучшими пожеланиями. – jachguate

ответ

4

Что мне нужно делать, если я должен был сделать что-то вроде этого поставить еще один TList на Данные, содержащие список всех объектов на нем. Заполните его в конструкторе, а затем, когда вам нужно сделать что-то подобное, используйте цикл, чтобы применить одну и ту же базовую операцию к каждому элементу в списке.

-3

Я буду осторожен здесь. Я знаю, что соблазн будет состоять в том, чтобы использовать общий интерфейс и отражение, или какую-то другую автоматизацию, которая является более гибкой и, честно говоря, более интересной для написания. Избегайте этого искушения. Нет ничего плохого в том, чтобы перечислять каждый элемент в списке в соответствии с вашим шаблоном. Образцы хороши, и код будет читабельным, простым в исполнении и легко модифицирует любое индивидуальное свойство, которое не соответствует шаблону.

Низкотехнологичный способ избежать ввода всего, чтобы использовать наш старый друг Excel. Поместите все свои свойства в колонке А, а затем использовать эту формулу в столбце B:

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

Хотя генерация кода в Excel - это хорошая вещь, которая есть в вашем наборе инструментов, я должен не согласиться с этим подходом. Если у него есть 1000 элементов для обработки, вы будете генерировать 1000 строк повторяющегося кода. Однако для таких вещей, как генерация операторов для управления таблицами и структурами базы данных (создание, выбор, вставка, разбор и т. Д.), Эта методика работает очень хорошо. –

+3

Трудно думать о более не-Дельфийском ответе. ;-) –

+0

Вы должны изучить все подходы и взвесить плюсы и минусы. Тот факт, что этот подход генерирует много строк кода и повторяется, сам по себе не является недостатком, когда дело касается производительности и будущего обслуживания.Поскольку только 1 человек предложил решение и жизнеспособный, мы должны сравнить недостатки. Какой код мы собираемся написать для нового свойства? Разве он не должен перечислить все свойства повторно? Теперь у нас есть еще 1000 строк повторяющегося кода, но у нас также есть новый элемент данных для создания, поддержки и хранения памяти. – cortijon

0

Может быть, я не понимая это хорошо, но ... Вот где объектно-ориентированный блестит. Вы определяете процедуру для класса и затем применяете для любого создаваемого вами экземпляра.

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; 

Надежда эта помощь Daniel

0

Судя по this post и this post, я хотел бы предложить следующее:

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. 

Теперь вы можете написать такой код:

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

Если вам нужны более сложные манипуляции на массиве было бы неплохо поместить его в класс - замените поля, которые вы написали, только на efield типа TDataArray, - и напишите функции для управления данными как методы этого класса.

Смежные вопросы