Эффективно изменить записи членов в Generics в Delphi XE - PullRequest
4 голосов
/ 15 марта 2012

AFAIK, мы не можем напрямую присваивать значения элементам записи, если указанная запись имеет общую структуру.

Например, имея:

type

TMyRec = record
  Width: integer;
  Height: integer;
end;

var
  myList: TList<TMyRec>;


...
  myList[888].Width:=1000; //ERROR here: Left side cannot be assigned.
...

До сих пор я использовал временную переменнуючтобы преодолеть это:

var
  ...
  temp: TMyRec;
  ...

begin
  ...
  temp:=myList[999];
  temp.Width:=1000;
  myList[999]:=temp;
  ...
end;

Уродливо, медленно, но работает.Но теперь я хочу добавить к TMyRec динамический массив:

type
  TMyRec = record
    Width: integer;
    Height: integer;
    Points: array or TPoint;
  end;

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

Вопрос в том, как изменить элемент записи, если эта запись имеет общую структуру, без необходимости копировать ее во временную переменную?

TIA для вашей обратной связи

1 Ответ

6 голосов
/ 15 марта 2012

Динамическая переменная массива - это просто ссылка на массив. Он хранится в записи в виде одного указателя. Таким образом, вы можете продолжить ваш текущий подход без какого-либо чрезмерного копирования. Копирование элемента во временную переменную только копирует ссылку на массив и не копирует содержимое массива. И даже лучше, если вы присваиваете элементы массива, тогда вам вообще не нужна копия. Вы можете написать:

myList[666].Points[0] := ...

Если у вас есть действительно большая запись, вам лучше использовать класс, а не запись. Поскольку экземпляр класса является ссылкой, применяется тот же аргумент, что и выше. Для этого подхода вы можете предпочесть TObjectList <> TList <>. Преимущество TObjectList <> заключается в том, что вы можете установить для свойства OwnsObjects значение True и позволить списку отвечать за уничтожение его членов.

Вы можете написать

var
  myList: TObjectList<TMyClass>
....
myList[666].SomeProp := NewValue;
...