Инициализация функции в типе.

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
skobanev
новенький
Сообщения: 33
Зарегистрирован: 24.02.2016 22:55:01
Откуда: Ростов-на-Дону
Контактная информация:

Инициализация функции в типе.

Сообщение skobanev »

Люди, помогите логику либо понять либо придумать. Реально уже клин поймал логики.

Есть вот такой код.

Код: Выделить всё

 tListItem = class (tPersistent)
  private
    prA : Integer;
    prB : String;
  public
    property a: integer read pra write pra;
    property b: string read prb write prb;
  end;

  tListObject = class (tList)
    function asDataSet : tMemDataSet;
  end;                                   
...
function tListObject.asDataSet : tMemDataSet;
var
  i: Integer;
begin
  result := tMemDataSet.Create(nil);
  result.Clear;
  result.FieldDefs.Add('id', ftInteger, 1);
  result.FieldDefs.Add('Name', ftString, 50);
  result.active := true;

  for i:= 0 to self.Count -1 do
  begin
    result.Insert;

//    result.Fields[0].SetData(@tListItem(self.Items[i]).a, true);
//    result.Fields[1].SetData(@tListItem(self.Items[i]).b, true);

    result.Fields[0].Value := tListItem(self.Items[i]).a;
    result.Fields[1].Value := tListItem(self.Items[i]).b;
  end;
 result.Post;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i, ItemNo : Integer;
begin
  ListObject := tListObject.Create;
  for i:=0 to 100000 do
  begin
    ItemNo := ListObject.Add(tListItem.Create);
    tListItem(ListObject.Items[ItemNo]).a := i;
    tListItem(ListObject.Items[ItemNo]).b := CurrToStr( (i*4)/15*8 );
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ds := tDataSource.Create(nil);
  ds.DataSet := ListObject.asDataSet;
  DBGrid1.DataSource := ds;
end;                                                                   


В Двух словах. Есть тип списка данных - tList. Для быстрого и безболезненного отображения - собираю все данные в MemDataSet и передаю на DBGrid.
Все нормально работает, только не совсем пойму как мне сделать либо перенести инициализацию объекта tMemDataSet , чтобы она очищалась после исполнения функции. А то получается что каждый раз после обращения к функции у меня создается новый экземпляр. пару тысяч раз обновил - и прога раздулась.

Добавлено спустя 23 минуты 17 секунд:
Все, прошу прощения, надо наверно отдыхать больше )))))

Код: Выделить всё

 tListObject = class (tList)
  private
    prDataSet : tMemDataSet;
  public
    function asDataSet : tMemDataSet;
  constructor Create;
  end;                               
...
constructor tListObject.Create;
begin
  inherited create;
  self.prDataSet := tMemDataSet.Create(nil);
end;

function tListObject.asDataSet : tMemDataSet;
var
  i: Integer;
begin
  self.prDataSet.clear;
  self.prDataSet.FieldDefs.Add('id', ftInteger, 1);
  self.prDataSet.FieldDefs.Add('Name', ftString, 50);

  self.prDataSet.active := true;
  for i:= 0 to self.Count -1 do
  begin
    self.prDataSet.Insert;
//    result.Fields[0].SetData(@tListItem(self.Items[i]).a, true);
//    result.Fields[1].SetData(@tListItem(self.Items[i]).b, true);

    self.prDataSet.Fields[0].Value := tListItem(self.Items[i]).a;
    self.prDataSet.Fields[1].Value := tListItem(self.Items[i]).b;
  end;
  self.prDataSet.Post;
  result := self.prDataSet;
end;                                 
DedFrend
постоялец
Сообщения: 157
Зарегистрирован: 25.11.2018 11:21:50

Сообщение DedFrend »

Неужели действительно нужно при каждом(!) обращении к asDataset копировать в набор данных 100000(!!!) записей ???
Короче, я бы делал так:

Код: Выделить всё

tListItem = class (tPersistent)
  private
    prA : Integer;
    prB : String;
  public
    property a: integer read pra write pra;
    property b: string read prb write prb;
  end;


     tListObject = class (tObjectList) // по-моему так лучше
      private
        fMDataset: tMemDataset;
      public
        property MDataset : tMemDataSet read fMDataset;
        constructor Create;
      end;                               
    ...
    constructor tListObject.Create;
    var
       i: integer;
       Item: tListItem;
    begin
      inherited create;
     for i:=0 to 100000 do
     begin
       Item:= tListItem.Create;
       Item.a := i;
      Item.b := CurrToStr( (i*4)/15*8 );
       Add(Item);
    end;
      fMDataset := tMemDataSet.Create(nil);
      MDataset.clear;
      MDataset.FieldDefs.Add('id', ftInteger);
      MDataSet.FieldDefs.Add('Name', ftString, 50);
      MDataSet.active := true;
      for i:= 0 to Count -1 do
      begin
        MDataSet.Insert;
        MDataSet.Fields[0].Value := self[i].a;
        MDataSet.Fields[1].Value := self[i].b;
      end;
      MDataSet.Post;
    end;


skobanev
новенький
Сообщения: 33
Зарегистрирован: 24.02.2016 22:55:01
Откуда: Ростов-на-Дону
Контактная информация:

Сообщение skobanev »

В этом тоже есть своя правда.
Я правда уже прикрутил обсчет к форме. Теперь когда надо объек кидаешь на объект формы и он сам все генерит.
Честно говоря очень трудно в идеологии перестраиваться с процедурного паскаля (лет 15 так программировал) на полностью объектную среду.
Все время хочется где нить какие нить переменные посохранять....
Ответить