![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
record в property [D6, Win2k]
sokoloff © (2002-07-02 16:13:00)День добрый, подскажите как правильно преписать код.
Есть:
type
TRow = record
Name: string;
Caption: string;
ID : integer;
Value: string;
end;
TMyTable = class
private
FRows: array[0..16] of TRow;
function GetValues(Index: integer): TRow;
procedure SetValues(Index: integer; const Value: TRow);
public
property Values[Index: integer]: TRow read GetValues write SetValues;
end;
function TMyTable.GetValues(Index: integer): TRow;
begin
result:=Frow[Index];
end;
procedure TMyTable.SetValues(Index: integer; const Value: TRow);
begin
FRow[Index]:=Value;
end;
Т.е. в классе есть свойство-массив Values, каждое значение это запись из нескольких полей.
Не работает такой код:
MyTable.Values[2].ID:=2;
Компилятор выдает:
[Error] UnitFLT.pas(174): Left side cannot be assigned to
Можно, конечно, сделать так:
var
NewRow: TRow;
begin
NewRow.ID:=2;
MyTable.Values[2]:=NewRow;
Но хотелось бы как в первом варианте. Можно как-нибудь переписать код класса чтоб можно было присваивать значения напрямую? Если можно, то как?
Sokoloff (2002-07-02 18:45:00) [1]Первый вариант не работает :(
А сделал я все гораздо проще, не public property которое ссылается на private array, а просто public array, т.е.
TMyTable = class
private
public
Values : array[0..16] of TRow;
end;
Плохо то,что нет возможности проверять значения перед записью, правда пока это и не надо, но как-то некрасиво. Но в вариантах с указателями, насколько я вижу это то-же невозможно. Чтоб проверять записи надо делать не record, а class.
Толик (2002-07-02 17:45:00) [2]Прошу прощения за опечатку, ф-я GetValues должна выглядеть так:
function TMyTable.GetValues(Index: integer): PRow;
begin
result := @Frow[Index];
end;
Толик (2002-07-02 17:40:00) [3]Надо объявить св-во с типом не структуры, а УКАЗАТЕЛЕЯ на структуру.
вот Ваш несколько видоизменённый код:
type
TRow = record
Name: string;
Caption: string;
ID : integer;
Value: string;
end;
PRow = ^TRow;
TMyTable = class
private
FRows: array[0..16] of TRow
function GetValues(Index: integer): PRow;
procedure SetValues(Index: integer; const Value: PRow);
public
property Values[Index: integer]: PRowread GetValues write SetValues;
end;
function TMyTable.GetValues(Index: integer): PRow;
begin
result := Frow[Index];
end;
procedure TMyTable.SetValues(Index: integer; const Value: PRow);
begin
FRow[Index]:=Value ^;
//а вот здесь следует помнить о том, что прежде чем передать в эту ф-ю значение Value, под него надо выделить память, а освобожлать её ТОЛЬКО ПОСЛЕ удаления эл-та из массива!!!
end;
Ну и соответственно обращаться к этому св-ву надо так:
MyTable.Values[2]^.ID:=2;
Dimka Maslov (2002-07-02 17:15:00) [4]type
PRow = ^TRow;
TRow = record
Name: string;
Caption: string;
ID : integer;
Value: string;
end;
TMyTable = class
private
FRows: array[0..16] of TRow;
function GetValues(Index: integer): PRow;
public
property Values[Index: integer]: PRow read GetValues; end;
function TMyTable.GetValues(Index: integer): PRow;
begin
result:=@Frow[Index];
end;
Ivan2 (2002-07-02 16:57:00) [5]Так как ты хочешь не может работать. Когда ты пишешь
MyTable.Values[2]:=NewRow, компилятор фактически
генерит след. код:MyTable.SetValues(2, NewRow)т.е. вызывает метод для присвоения значения твоему
свойству. Если хочешь, открой во время выполнения этой строчки окно ассемблерного кода. Естественно, что записьMyTable.Values[2].ID:=2в этом случае некорректна в левой части присваивания (заметь, в правой - без проблем).
Попробуй переписать свой класс так:
type
TRowArray: array[0..16] of TRow;
TMyTable = class
private
FRows: TRowArray;
function GetValues(Index: integer): TRow;
procedure SetValues(Index: integer; const Value: TRow);
public
property Values: TRowArray read FRows;
// property Values[Index: integer]: TRow read GetValues write SetValues;
end;
Тогда ты смошеь обрашяться к массиву свободно и без извращений:
MyTable.Values[2] := NewRow
MyTable.Values[2].ID := 2
MyTable.Values[3].Name := MyTable.Values[10].Name
и т.д.