-
У компонента есть свойство, представлющее из себя массив записей с числовой индексацией. Хочу изменить только одно из свойств записи из массива:UsersList[c].State:=isIdle;
[Pascal Error] Unit1.pas(258): E2064 Left side cannot be assigned to
Что нужно поменять или как лучше это сделать по-другому?
код компонента:
type
TState = (isIgnore, isInstructed, isIdle, isChating);
TUser = packed record
P1: cardinal;
P2: String;
P3: TState;
P4: String;
end;
TAUser = array of TUser;
TUsersList = class
private
FUsers: TAUser;
FCount: integer;
function FUserRead(P1: Cardinal):TUser;
procedure FUserWrite(P1: Cardinal; const User:TUser);
public
...
function UserIndex(P1: Cardinal):integer;
property User[P1: Cardinal]:TUser
read FUserRead
write FUserWrite; default;
end;
implementation
...
function TUsersList.UserIndex(P1: Cardinal):integer;
var
i:integer;
begin
Result:=-1; // если не найдем будет -1
for i:=0 to FCount - 1 do begin
if FUsers[i].P1=P1 then begin
Result:=i;
Break;
end;
end;
end;
function TUsersList.FUserRead(P1: Cardinal):TUser;
var
n:integer;
begin
n:=UserIndex(P1);
if (n<0) OR (n>=FCount) then raise EUsersListError.CreateFmt(SUsersListIndexError, [n]);
Result:=FUsers[n];
end;
procedure TUsersList.FUserWrite(P1: Cardinal; const User:TUser);
var
n:integer;
begin
n:=UserIndex(P1);
if (n>0) AND (n<FCount) then begin
// такой номер уже есть в списке
FUsers[n]:=User;
end
else begin
// такого номера еще нет в списке
inc(FCount);
SetLength(FUsers,FCount);
FUsers[FCount-1]:=User;
end;
end; -
DimaBr © (02.04.10 09:03) [1]Возможны 2 варианта:
1.UsersList[c] := Function(P1,P2,isIdle,P4);
2.property UserState[Index: integer]:TState read GetUserState write SetUserState; -
DimaBr © (02.04.10 15:47) [2]По коду:
1. Методы доступа принято именовать Get... и Set...
2. Проверкаif n>=FCount then
просто лишняя
3. Поле FCount - лишнее
4. Функцию UserIndex можно сделать корочеfunction TUsersList.UserIndex(P1: Cardinal):integer;
begin
for Result := 0 to High(FUsers) do
if FUsers[Result].P1=P1 then Exit;
Result:=-1; // если не найдем будет -1
end; -
Спасибо, воспользовался вторым вариантом :)
-
> 1. Методы доступа принято именовать Get... и Set...
Уже сам исправил, поздно ночью уже плохо соображал :)
> 2. Проверкаif n>=FCount
then просто лишняя
Имеется ввидуif (n<0) OR (n>=FCount) then raise ...
?
> 3. Поле FCount - лишнее
Спасибо, не знал что так можноHigh(FUsers)
:)
> 4. Функцию UserIndex можно сделать короче
Учту. -
Дмитрий Белькевич (16.05.10 16:26) [5]
> if (n<0) OR (n>=FCount)
Можно еще так: if not InRange(n, 0, FCount - 1) then ...
если с краями не напутал. -
alexrayne (18.05.10 22:20) [6]TUser = packed record
P1: cardinal;
P2: String;
P3: TState;
P4: String;
end;
запись то у вас немаленькая. она полюбому бедет передаваться адресом, посему я бы сделал свойство ваше вместо массива записей - массивом адресов на запись. в таком случаеUsersList[c].State:=isIdle;
становится нормальным и компилируемым
тобиш я бы сдела чтото вроде етого:
SomeUserData = packed record
P1: cardinal;
P2: String;
P3: TState;
P4: String;
end;
SomeUserDataAccess = ^SomeUserData;
TAUser = array of TUser;
TUsersList = class
private
FUsers: TAUser;
FCount: integer;
function FUserRead(P1: Cardinal):SomeUserDataAccess;
procedure FUserWrite(P1: Cardinal; const User:SomeUserDataAccess);
public
...
function UserIndex(P1: Cardinal):integer;
property User[P1: Cardinal]:SomeUserDataAccess
read FUserRead
write FUserWrite; default;
end;
procedure TUsersList.FUserWrite(P1: Cardinal; const User:SomeUserDataAccess);
var
n:integer;
begin
n:=UserIndex(P1);
if (n>0) AND (n<FCount) then begin
// такой номер уже есть в списке
FUsers[n]:=User;
end
else begin
// такого номера еще нет в списке
inc(FCount);
SetLength(FUsers,FCount);
FUsers[FCount-1]:=User^;
end;
end; -
alexrayne (18.05.10 22:23) [7]конешно напортачил, но мысль вроде засветил