function GetItem(const Index: string): string;
procedure SetItem(const Index, Value: string);
property Items[Index: string]: string read GetItem write SetItem;
Свойства-массивы
http://www.rsdn.ru/, ->Статьи->Delphi->Программирование на языке Delphi.Учебное пособие). В главе 3 есть раздел: "3.6.3. Свойства-массивы".
Так вот, читаю там следующее (цитата):
Свойства-массивы имеют два важных отличия от обычных массивов:
их индексы не ограничиваются диапазоном и могут иметь любой тип данных, а не только Integer. Например, можно создать свойство-массив, в котором индексами будут строки. Обращение к такому свойству могло бы выглядеть примерно так:
Reader.Items['FirstName'] := 'Alexander';
...
Больше ничего. Очень интересно, а как сделать такое? Как использовать: понятно. А как правильно объявить такой массив?
Набрел на онлайновую книгу по Дельфи (
Так вот, читаю там следующее (цитата):
Свойства-массивы имеют два важных отличия от обычных массивов:
их индексы не ограничиваются диапазоном и могут иметь любой тип данных, а не только Integer. Например, можно создать свойство-массив, в котором индексами будут строки. Обращение к такому свойству могло бы выглядеть примерно так:
Reader.Items['FirstName'] := 'Alexander';
...
Больше ничего. Очень интересно, а как сделать такое? Как использовать: понятно. А как правильно объявить такой массив?
Цитата: Freeman
Код:
function GetItem(const Index: string): string;
procedure SetItem(const Index, Value: string);
property Items[Index: string]: string read GetItem write SetItem;
procedure SetItem(const Index, Value: string);
property Items[Index: string]: string read GetItem write SetItem;
Делаю:
Код:
unit Unit2;
interface
type
TDelimitedReader = class
FItems: array of string;
constructor create();
function GetItem(const Index: string): string;
procedure SetItem(const Index, Value: string);
end;
implementation
constructor TDelimitedReader.create;
begin
SetLength(FItems, 1);
end;
function TDelimitedReader.GetItem(const Index: string): string;
begin
Result := FItems[Index];
end;
procedure TDelimitedReader.SetItem(const Index, Value: string);
begin
FItems[Index] := Value;
end;
interface
type
TDelimitedReader = class
FItems: array of string;
constructor create();
function GetItem(const Index: string): string;
procedure SetItem(const Index, Value: string);
end;
implementation
constructor TDelimitedReader.create;
begin
SetLength(FItems, 1);
end;
function TDelimitedReader.GetItem(const Index: string): string;
begin
Result := FItems[Index];
end;
procedure TDelimitedReader.SetItem(const Index, Value: string);
begin
FItems[Index] := Value;
end;
Получаю: [Pascal Error] Unit2.pas(32): E2010 Incompatible types: 'Integer' and 'string'
Цитата: dominator
Делаю:
Получаю: [Pascal Error] Unit2.pas(32): E2010 Incompatible types: 'Integer' and 'string'
Код:
unit Unit2;
interface
type
TDelimitedReader = class
FItems: array of string;
constructor create();
function GetItem(const Index: string): string;
procedure SetItem(const Index, Value: string);
end;
implementation
constructor TDelimitedReader.create;
begin
SetLength(FItems, 1);
end;
function TDelimitedReader.GetItem(const Index: string): string;
begin
Result := FItems[Index];
end;
procedure TDelimitedReader.SetItem(const Index, Value: string);
begin
FItems[Index] := Value;
end;
interface
type
TDelimitedReader = class
FItems: array of string;
constructor create();
function GetItem(const Index: string): string;
procedure SetItem(const Index, Value: string);
end;
implementation
constructor TDelimitedReader.create;
begin
SetLength(FItems, 1);
end;
function TDelimitedReader.GetItem(const Index: string): string;
begin
Result := FItems[Index];
end;
procedure TDelimitedReader.SetItem(const Index, Value: string);
begin
FItems[Index] := Value;
end;
это естественно, т.к. FItems это не ассоциативный массив, обращаться к элементам можно только по индексам
Цитата: Михаил
это естественно, т.к. FItems это не ассоциативный массив, обращаться к элементам можно только по индексам
Извините, недопонял:)
Здесь же это выглядит именно как ассоциативный массив, или нет:
Reader.Items['FirstName'] := 'Alexander';
В приведенном выше коде попытался развернуть решение от Freeman.
Где ошибся? Ведь function GetItem(const Index: string): string; как раз таки предполагает обращение по индексу, который является строкой?
Цитата: dominator
Извините, недопонял:)
Здесь же это выглядит именно как ассоциативный массив, или нет:
Reader.Items['FirstName'] := 'Alexander';
В приведенном выше коде попытался развернуть решение от Freeman.
Где ошибся? Ведь function GetItem(const Index: string): string; как раз таки предполагает обращение по индексу, который является строкой?
Здесь же это выглядит именно как ассоциативный массив, или нет:
Reader.Items['FirstName'] := 'Alexander';
В приведенном выше коде попытался развернуть решение от Freeman.
Где ошибся? Ведь function GetItem(const Index: string): string; как раз таки предполагает обращение по индексу, который является строкой?
если быть точным то данное объявление функции предполагает только передачу одно параметра типа string и все а то что индекс будет типа string предполагает соответствующее объявление property :). То что написал Freeman это описание ассоциативного свойства-массива, а FItems таковым не является.
Код:
type
tc=class
FItems:array of string;
...
property Items[Index:string]:string read .... write ...;
end;
var c:tc;
c.Items['myIndex']:='myValue';//works!
c.FItems['myIndex']:='myValue';// don`t work :(
tc=class
FItems:array of string;
...
property Items[Index:string]:string read .... write ...;
end;
var c:tc;
c.Items['myIndex']:='myValue';//works!
c.FItems['myIndex']:='myValue';// don`t work :(
dominator, не путай свойство-массив (индексатор) и массив. Это абсолютно разные вещи. В простых массивах ты можешь использовать только целочисленные индексы. Обращение же к свойству массиву просто транслируется компилятором в вызов соответствующего метода, внутри которого ты можешь делать все, что угодно.
Код:
type
TStringByString = class
private
FItems: TStrings;
function GetItem(const Index: string): string;
procedure SetItem(const Index, Value: string);
public
constructor Create;
destructor Destroy; override;
property Items[Index: string]: string read GetItem write SetItem;
end;
{ TStringByString }
constructor TStringByString.Create;
begin
FItems := TStringList.Create;
end;
destructor TStringByString.Destroy;
begin
FItems.Free;
end;
function TStringByString.GetItem(const Index: string): string;
begin
Result := FItems.Values[Index];
end;
procedure TStringByString.SetItem(const Index, Value: string);
begin
FItems.Index[Index] := Value;
end;
TStringByString = class
private
FItems: TStrings;
function GetItem(const Index: string): string;
procedure SetItem(const Index, Value: string);
public
constructor Create;
destructor Destroy; override;
property Items[Index: string]: string read GetItem write SetItem;
end;
{ TStringByString }
constructor TStringByString.Create;
begin
FItems := TStringList.Create;
end;
destructor TStringByString.Destroy;
begin
FItems.Free;
end;
function TStringByString.GetItem(const Index: string): string;
begin
Result := FItems.Values[Index];
end;
procedure TStringByString.SetItem(const Index, Value: string);
begin
FItems.Index[Index] := Value;
end;
Главное, правильно объявить методы чтения/записи индексируемого свойства. Вот конкретный пример использования свойства со строковым индексом.
Код:
var
list: TStringList;
val: string;
begin
list := TStringList.Create;
list.Add ('Вася=Юзер');
val := list.values ['Вася']; // значение - "Юзер"
list.values['Вася'] := 'Хакер';
val := list.Strings [0]; //значение "Вася=Хакер"
end;
list: TStringList;
val: string;
begin
list := TStringList.Create;
list.Add ('Вася=Юзер');
val := list.values ['Вася']; // значение - "Юзер"
list.values['Вася'] := 'Хакер';
val := list.Strings [0]; //значение "Вася=Хакер"
end;
Соответственно, объявление свойства выглядит так:
Код:
function GetValue (const Name: string): string;
procedure SetValue (const Name, Value: string);
property Value [Name: string]: string read GetValue write SetValue ;
procedure SetValue (const Name, Value: string);
property Value [Name: string]: string read GetValue write SetValue ;
Спасибо всем большое, все ясно.