![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Динамический массив структур (record) как свойство класса. [D7, XP]
SingleStranger © (2009-02-11 13:19:00)Как реализовать?
Меня интересует способ с простым доступом к любому полю структуры.
Что-то типа того:
TRec = record
field1: integer;
field2: string;
end;
TSomeClass = class
private
FSRec: array of TRec;
function GetSRec(Index: Integer): TRec;
procedure SetSRec(Index: Integer; const Value: TRec);
public
function SRecAddNew: Integer;
function SRecAdd(Value: TRec): Integer;
property SRec[Index: Integer]: TRec read GetSRec write SetSRec;
end;
И доступ, чтобы был простым, примерно так:
var
i: integer;
r: TRec;
begin
r.field1 := 1;
r.field2 := 'aaa';
i := SomeClass.SRecAdd(r);
SomeClass.SRec[i].field2 := 'bbb';
end;
или как-то так:
var
i: integer;
begin
i := SomeClass.SRecAddNew();
SomeClass.SRec[i].field2 := 'bbb';
end;
Ega23 (2009-02-11 14:20:00) [41]
> А проще не получится?
Вот проще (сугубо ИМХО):
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Contnrs;
type
TSomeClass = class (TObject)
private
FField1 : Integer;
FField2: string;
public
procedure Assign(source : TSomeClass);
property Field1 : Integer read FField1 write FField1;
property Field2 : string read FField2 write FField2;
end;
TSomeClassContainer = class (TObject)
private
FItems : TObjectList;
function GetCount: Integer;
function GetItem(Index: Integer): TSomeClass;
procedure SetItem(Index: Integer; const Value: TSomeClass);
public
constructor Create;
destructor Destroy; override;
function AddItem(Item : TSomeClass) : Integer;
procedure DeleteItem(Index : Integer);
procedure Clear;
property Items[Index : Integer] : TSomeClass read GetItem write SetItem;
property Count : Integer read GetCount;
end;
implementation
{ TSomeClass }
procedure TSomeClass.Assign(source: TSomeClass);
begin
FField1 := source.FField1;
FField2 := source.FField2;
end;
{ TSomeClassContainer }
function TSomeClassContainer.AddItem(Item: TSomeClass): Integer;
begin
Result := FItems.Add(Item);
end;
procedure TSomeClassContainer.Clear;
begin
FItems.Clear;
end;
constructor TSomeClassContainer.Create;
begin
FItems := TObjectList.Create(True);
end;
procedure TSomeClassContainer.DeleteItem(Index: Integer);
begin
FItems.Delete(Index);
end;
destructor TSomeClassContainer.Destroy;
begin
FItems.Free;
inherited;
end;
function TSomeClassContainer.GetCount: Integer;
begin
Result := FItems.Count;
end;
function TSomeClassContainer.GetItem(Index: Integer): TSomeClass;
begin
try
Result := TSomeClass(FItems.Items[i]);
except
Result := nil;
end;
end;
procedure TSomeClassContainer.SetItem(Index: Integer;
const Value: TSomeClass);
begin
TSomeClass(FItems.Items[Index]).Assign(Value);
end;
end.
В данном варианте контейнер спрятан в private и доступ к нему идёт через public-функции.
SingleStranger (2009-02-11 14:10:00) [42]
> Anatoly Podgoretsky © (11.02.09 14:01) [10]
> Проще вариант со свойствами.
Это как? Массив свойств?
> Anatoly Podgoretsky © (11.02.09 14:00) [9]
> тогда сделай функции присвоения и вызывай их.
Если это единственный способ, то видимо придется. Хотя, если честно, мне он не нравится.
> Ega23 © (11.02.09 13:55) [6]
> ... я бы TRec сделал классом, а в TSomeClass
> либо TObjectList в привате организовал с методами доступа ...
Обдумывал и этот вариант, но как-то не хотелось городить класс для, вобщем-то, простой структуры. Это просто настроечная структура, там куча полей простого типа. Но может и над классом подумаю.
Есть еще варианты?
Anatoly Podgoretsky (2009-02-11 14:01:00) [43]> SingleStranger (11.02.2009 13:55:08) [8]
Проще вариант со свойствами.
Anatoly Podgoretsky (2009-02-11 14:00:00) [44]> SingleStranger (11.02.2009 13:55:07) [7]
Тебе привели два решения, а ты губы морщишь.
Не нравится предложеные, тогда сделай функции присвоения и вызывай их.
SingleStranger (2009-02-11 13:55:00) [45]
> Anatoly Podgoretsky © (11.02.09 13:48) [5]
> > SingleStranger (11.02.2009 13:19:00) [0]У тебя нет свойства
> SomeClass.SRec[i].field2Или делай свойство или копируй во
> временную переменную.
Т.е.?
var
i: integer;
r: TRec;
begin
i := 0;
r := SomeClass.SRec[i];
r.field2 := 'bbb';
SomeClass.SRec[i] := r;
end;
Так? Это еже неудобно.
А проще не получится?
SingleStranger (2009-02-11 13:55:00) [46]
> Anatoly Podgoretsky © (11.02.09 13:48) [5]
> > SingleStranger (11.02.2009 13:19:00) [0]У тебя нет свойства
> SomeClass.SRec[i].field2Или делай свойство или копируй во
> временную переменную.
Т.е.?
var
i: integer;
r: TRec;
begin
i := 0;
r := SomeClass.SRec[i];
r.field2 := 'bbb';
SomeClass.SRec[i] := r;
end;
Так? Это еже неудобно.
А проще не получится?
Ega23 (2009-02-11 13:55:00) [47]Если честно, то я бы TRec сделал классом, а в TSomeClass либо TObjectList в привате организовал с методами доступа, либо сам TSomeClass от TObjectList унаследовал (это уже от логики зависит).
Anatoly Podgoretsky (2009-02-11 13:48:00) [48]> SingleStranger (11.02.2009 13:19:00) [0]
У тебя нет свойства SomeClass.SRec[i].field2
Или делай свойство или копируй во временную переменную.
SingleStranger (2009-02-11 13:46:00) [49]
> SingleStranger (11.02.09 13:43) [2]
> Помоему, "Left side cannot be assigned to"
При доступе к полю структуры.
Ega23 (2009-02-11 13:44:00) [50]
TSomeClass = class
private
FSRec: array of TRec;
function GetSRec(Index: Integer): TRec;
procedure SetSRec(Index: Integer; const Value: TRec);
public
function SRecAdd(Value: TRec): Integer;
property SRec[Index: Integer]: TRec read GetSRec write SetSRec;
end;
function TSomeClass.GetSRec(Index: Integer): TRec;
begin
Result := FSRec[Index];
end;
procedure TSomeClass.SetSRec(Index: Integer; const Value: TRec);
begin
FSRec[Index].field1 := Value.field1;
FSRec[Index].field2 := Value.field2;
end;
function TSomeClass.SRecAdd(Value: TRec): Integer;
begin
SetLength(FSRec, Hight(FSRec) + 1);
SetSRec(Hight(FSRec), Value);
Result := Hight(FSRec);
end;
Что-то типа этого.
P.S. С динамическими массивами практически не работал, поэтому не уверен, как правильно отработает
procedure TSomeClass.SetSRec(Index: Integer; const Value: TRec);
begin
FSRec[Index].field1 := Value.field1;
FSRec[Index].field2 := Value.field2;
end;
Возможно достаточноFSRec[Index] := Value;
Надо проверять.
SingleStranger (2009-02-11 13:43:00) [51]
> clickmaker © (11.02.09 13:39) [1]
> и в чем проблема?
Помоему, "Left side cannot be assigned to", если не ошибаюсь. Я код-то переписал, но нынешний вариант, вообще не устраивает. Вот и решил спросить.
clickmaker (2009-02-11 13:39:00) [52]и в чем проблема?