Записать record в TObject

Ognev

ex-Team DUMPz
Местный
Регистрация
20 Авг 2004
Сообщения
2,079
Реакции
908
Credits
0
Всем доброго времени суток!

Извиняюсь, если тупой вопрос, но чего-то не осилил. Подскажите, как можно в TObject записать record и с ней потом работать. Пока не получилось даже что-то записать. В старом коде вместо record был class TCoverReliefPiar, и все работало (UserObject : TObject ):
NewGrid.UserObject := TCoverReliefPiar.Create;
Можно ли вместо класса засунуть туда запись?

UPD
Delphi XE10 Seatle.
 
Последнее редактирование модератором:

rgreat

Местный
Регистрация
24 Дек 2009
Сообщения
35
Реакции
32
Credits
70
Можно, но без програмиста не выйдет.
 

LeshaRB

Свой
Регистрация
11 Июн 2007
Сообщения
319
Реакции
467
Credits
25
Там надо делать обертку классом, что лучше имхо

type
PMyRec = ^TMyRec;
TMyRec = record
I : integer;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
P : PMyRec;
begin
New(P);
P.I := 42;
ListBox1.AddItem('One',TObject(P));
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
I : integer;
begin
//Free memory
for I := 0 to ListBox1.Items.Count - 1 do
Dispose(PMyRec(ListBox1.Items.Objects));
end;

procedure TForm1.ListBox1Click(Sender: TObject);
var
P : PMyRec;
begin
P := PMyRec(ListBox1.Items.Objects[ ListBox1.ItemIndex ]);
ShowMessage( IntToStr(P.I) );
end;
 

JCDenton

Местный
Регистрация
15 Фев 2013
Сообщения
15
Реакции
3
Credits
28
Проблемы не увидел:

type
TCoverReliefPiar = record
Param: Integer;
end;

TNewGrid = class(...)
private
FUserObject: TCoverReliefPiar;
public
property UserObject: TCoverReliefPiar read FUserObject write FUserObject;
end;

...

var
NewGrid: TNewGrid;
CoverReliefPiar: TCoverReliefPiar;

...

CoverReliefPiar.Param := 1;
NewGrid.UserObject := CoverReliefPiar;

Если вопрос в этом:
NewGrid.UserObject.Param := 1;
то так - нельзя. Записи передаются по значению (в отличие от объектов классов) - следовательно, можно поменять только всё значение целиком (всю запись).

Но можно так:
type
TCoverReliefPiar = record
Param: Integer;
end;
PCoverReliefPiar = ^TCoverReliefPiar;

TNewGrid = class(...)
private
FUserObject: TCoverReliefPiar;
function GetUserObject: PCoverReliefPiar;
procedure SetUserObject(const AValue: PCoverReliefPiar);
public
property UserObject: PCoverReliefPiar read GetUserObject write SetUserObject;
end;

function TNewGrid.GetUserObject: PCoverReliefPiar;
begin
Result := @FUserObject;
end;

procedure TNewGrid.SetUserObject(const AValue: PCoverReliefPiar);
begin
Assert(Assigned(AValue));
FUserObject := AValue^;
end;

...

var
NewGrid: TNewGrid;

...

NewGrid.UserObject.Param := 1;

В этом случае свойство передаётся по указателю.

Если вопрос в этом:
type
TEmptyRecord = record
end;

TCoverReliefPiar = record
Param: Integer;
end;

TNewGrid = class(...)
private
FUserObject: TEmptyRecord;
public
property UserObject: TEmptyRecord read FUserObject write FUserObject;
end;

...

var
NewGrid: TNewGrid;
CoverReliefPiar: TCoverReliefPiar;

...

CoverReliefPiar.Param := 1;
NewGrid.UserObject := CoverReliefPiar;
то - нет, так нельзя. Передача по значению означает статический размер. Наследования в записях нет.

Можно, опять же, переделать всё на указатели, ввести первое поле, определяющее тип/размер записи (на манер dwSize в WinAPI). Но смысл это делать, если есть гораздо более удобные объекты/классы?
 
Последнее редактирование модератором:

Ognev

ex-Team DUMPz
Местный
Регистрация
20 Авг 2004
Сообщения
2,079
Реакции
908
Credits
0
Общее короткое резюме по этому вопросу именно что нужно делать обертку классом. И хранить запись в свойстве или поле - в зависимости от того, что требуется делать с записью и как. Иначе получается извращение.

Всем спасибо за ответы!
 

utmost

Местный
Регистрация
21 Ноя 2009
Сообщения
14
Реакции
5
Credits
25
Сериализовать запись в JSON объект, с каких-то последних версий дельфи он вроде из коробки есть, и передавать как строку его удобнее, хоть по сети кидай, хоть между приложениями или окнами.