Индексные свойства ведут себя аналогично полям-массивам и используются, как правило, для доступа к элементам контейнеров. Как и при использовании обычных свойств, при использовании индексных свойств могут попутно выполняться некоторые действия.
Индексное свойство описывается в классе следующим образом:
property Prop[
описание индексов
]:тип
readIndexedPropertyReader
writeIndexedPropertyWriter
;
В качестве
может
выступать: IndexedPropertyReader
В качестве
может
выступать: IndexedPropertyWriter
Функция чтения и процедура записи должны быть методами этого класса и иметь следующий вид:
function GetProp(
описание индексов
):тип
;
procedure SetProp(описание индексов
; value:тип
);
В простейшем случае одного индекса описание индексного свойства выглядит так:
property Prop[ind:
тип индекса
]:тип
read GetProp write SetProp;
Всякий раз, когда мы для объекта a
, содержащего свойство
Prop
, выполняем присваивание a.Prop[ind] := value
,
вызывается процедура a.SetProp(ind,value)
, а
когда считываем значение
a.Prop[ind]
, вызывается функция
a.GetProp(ind)
.
Индексное свойство, после которого добавлено ключевое слово default
с последующей ;
, называется индексным
свойством по умолчанию и позволяет пользоваться объектами класса как массивами, т.е.
использовать запись a[ind]
вместо a.Prop[ind]
.
Принципиальное отличие индексных свойств от полей-массивов состоит в том, что тип индекса может быть произвольным (в частности, строковым). Это позволяет легко реализовать так называемые ассоциативные массивы, элементы которых индексируются строками.
В следующем примере индексное свойство используется для закрашивания клеток шахматной доски белым или в графическом режиме.
uses GraphWPF;
const
n = 8;
sz = 50;
type
ChessBoard = class
private
a: array [,] of boolean := new boolean[n,n];
procedure setCell(x,y: integer; value: boolean);
begin
if value then
Brush.Color := Colors.White
else Brush.Color := Colors.Gray;
FillRectangle((x-1)*sz+1,(y-1)*sz+1,sz,sz);
a[x-1,y-1] := value;
end;
function getCell(x,y: integer) := a[x-1,y-1];
public
property Cells[x,y: integer]: boolean read getCell write setCell; default;
end;
var c: ChessBoard := new ChessBoard;
begin
for var x:=1 to n do
for var y:=1 to n do
c[x,y] := Odd(x+y);
end.
Можно не писать отдельные методы getCell
и setCell
для доступа к свойству на чтение и запись, а воспользоваться расширенными
индексными свойствами:
type
ChessBoard = class
private
a: array [,] of boolean := new boolean[n,n];
public
property Cells[x,y: integer]: boolean
read a[x-1,y-1]
write begin
if value then
Brush.Color := Colors.White
else Brush.Color := Colors.Gray;
FillRectangle((x-1)*sz+1,(y-1)*sz+1,sz,sz);
a[x-1,y-1] := value;
end; default;
end;