Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.219.236.62] |
|
Сообщ.
#1
,
|
|
|
Запутался...
Как сделать глубокую копию списка объектов? Ниже пробовал через Select, но фиг поймет не работает, при изменении данных в одном из списков меняется другой список тоже (комметами пометил важные места кода). Специально определил деструктор Tperson чтобы отследить удаления, но как видите удаляются всего 3 объекта, куда делись еще 3!!! Я вроде создаю на каждой итерации новый объект TPerson или нет? unit uPersonDemo; interface uses System.SysUtils, Spring.Collections; type TPerson = class public Name: string; Age: integer; constructor Create(AName: string; AAge: integer); destructor Destroy; override; end; procedure ProcessPersons; implementation { TPerson } constructor TPerson.Create(AName: string; AAge: integer); begin Name:= AName; Age:= AAge; end; destructor TPerson.Destroy; begin Writeln('--> TPerson deleting...'); inherited; end; procedure ProcessPersons; begin var persons := TCollections.CreateObjectList<TPerson>([ TPerson.Create('Gregory', 42), TPerson.Create('Mark', 27), TPerson.Create('Julia', 23) ]); var personsCopy := TEnumerable.Select<TPerson, TPerson>( TCollections.CreateList<TPerson>(persons), function (p: TPerson): TPerson begin Result := TPerson.Create(p.Name, p.Age); // new person end); persons[0].Name := 'XXX'; // change person name // output for var p in persons do begin Writeln(Format('%s', [p.Name])); end; Writeln; for var p in personsCopy do begin Writeln(Format('%s', [p.Name])); end; Writeln; end; end. Выхлоп XXX Mark Julia XXX Mark Julia --> TPerson deleting... --> TPerson deleting... --> TPerson deleting... |
Сообщ.
#2
,
|
|
|
Проделал следующее, добавил символ ` после имени персоны чтобы было видно где какие данные
... var personsCopy := TEnumerable.Select<TPerson, TPerson>( TCollections.CreateList<TPerson>(persons), function (p: TPerson): TPerson begin Result := TPerson.Create(p.Name + '`', p.Age); //<-- add ` sign end ); ... Теперь выхлоп такой XXX Mark Julia XXX` Mark` Julia` --> TPerson deleting... --> TPerson deleting... --> TPerson deleting... Это как могло получиться? |
Сообщ.
#3
,
|
|
|
Разобрался!
Короче Select операция ленивая, т.е. при ее вызове мы нифига не получаем! Да-да не удивляйтесь! А чтобы селект вернул результат надо применить к нему какую-либо, так называемую энергичную операцию, например ToArray: ... var personsCopy := TEnumerable.Select<TPerson, TPerson>( TCollections.CreateList<TPerson>(persons), function (p: TPerson): TPerson begin Result := TPerson.Create(p.Name, p.Age); //<-- new person end ) .ToArray; //<-- ... Теперь вывод правильный XXX Mark Julia Gregory Mark Julia --> TPerson deleting... --> TPerson deleting... --> TPerson deleting... Теперь по поводу удаления 3х объектов из 6. Тут при вызове селект я передаю ему результат CreateList<TPerson>(persons), а он не контролит создаваемые внутри объекты. Надо бы заюзать CreateObjectList, но не при передаче в селект, а обернуть им сам селект, тогда можно убрать вызов ToArray, поскольку сама передача селекта в CreateObjectList активирует операцию селект: var personsCopy := TCollections.CreateObjectList<TPerson>( //<-- TEnumerable.Select<TPerson, TPerson>( persons, function (p: TPerson): TPerson begin Result := TPerson.Create(p.Name, p.Age); end ) ); Выхлоп XXX Mark Julia Gregory Mark Julia --> TPerson deleting... --> TPerson deleting... --> TPerson deleting... --> TPerson deleting... --> TPerson deleting... --> TPerson deleting... ВСЕ! |