Reputation: 4624
I have this code:
type
TMyClass = class
private
procedure SetKeyValue(const Key: WideString; Value: Widestring);
function GetKeyValue(const Key: WideString): WideString;
public
// this works
property KeyValue[const Index: WideString] : WideString read GetKeyValue write SetKeyValue;
// this does not compile
// [Error]: Incompatible types: 'String' and 'Integer'
property Speed: WideString index 'SPEED' read GetKeyValue write SetKeyValue;
end;
The Speed
property gives me error:
Incompatible types: 'String' and 'Integer'
I need the index to be string.
Is it possible to use the index
with string value?
Upvotes: 2
Views: 2293
Reputation: 9
You can do it this way
type
// Class with Indexed properties
TRectangle = class
private
fCoords: array[0..3] of Longint;
function GetCoord(Index: string): Longint;
procedure SetCoord(Index: string; Value: Longint);
public
property Left : Longint Index 0 read GetCoord write SetCoord;
property Top : Longint Index 1 read GetCoord write SetCoord;
property Right : Longint Index 2 read GetCoord write SetCoord;
property Bottom : Longint Index 3 read GetCoord write SetCoord;
property Coords[Index: string] : Longint read GetCoord write SetCoord;
end;
const
IndexCoordMap:array [0..3] of TIdentMapEntry
(
(Value: 0; Name: 'Left'),
(Value: 1; Name: 'Top'),
(Value: 2; Name: 'Right'),
(Value: 3; Name: 'Bottom')
);
implementation
{$R *.dfm}
// TRectangle property 'Getter' routine
function TRectangle.GetCoord(Index: string): Longint;
var IntIndex: Integer;
begin
// Only allow valid index values
if (IdentToInt(Index, IntIndex, IndexCoordMap))
then Result := fCoords[IntIndex]
else raise Exception.Create('Invalid index');
end;
// TRectangle property 'Setter' routine
procedure TRectangle.SetCoord(Index: string; Value: Integer);
var IntIndex: Integer;
begin
// Only allow valid index values
if (IdentToInt(Index, IntIndex, IndexCoordMap))
then fCoords[IntIndex] := Value
else raise Exception.Create('Invalid index');
end;
Upvotes: 0
Reputation:
It works very well
property Values[const Name: string]: string read GetValue write SetValue;
{ClassName=class}
private
fArrayKey: Array of String;{1}
fArrayValue: Array of String;{2}
procedure Add(const Name, Value: string);
function GetValue(const Name: string): string;
procedure SetValue(const Name, Value: string);
published
property Values[const Name: string{1}]: string{2} read GetValue write SetValue;
function {ClassName.}GetValue(const Name: string): string;
Var I:integer;
Begin
Result := '#empty';
for I := low(fArrayKey) to high(fArrayKey) do
if fArrayKey[i]=Name then
Begin
Result := fArrayValue[i];
Break
End;
If result='#empty' the Raise Exception.CreateFmt('Key %s not found',[name]);
End;
procedure {ClassName.}SetValue(const Name, Value: string);
var i,j:integer
Begin
j:=-1;
for I := low(fArrayKey) to high(fArrayKey) do
if fArrayKey[i]=Name then
Begin
j:= i;
Break
End;
If j=-1 then Add(name,value) else fArrayValue[i]:= Value;
End;
procedure {ClassName.}Add(const Name, Value: string);
begin
SetLength(fArrayKey,Length(fArrayKey)+1);
SetLength(fArrayValue,Length(fArrayValue)+1);
fArrayKey [Length(fArrayKey) -1] := Name;
fArrayValue[Length(fArrayValue)-1] := Value;
end;
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Properties_(Delphi)
Upvotes: 0
Reputation: 596397
This is simply not possible with an index
specifier, as it only supports integral indexes. You will have to use a separate set of property getter/setter methods:
type
TMyClass = class
private
...
procedure SetSpeed(const Value: WideString);
function GetSpeed: WideString;
public
...
property Speed: WideString read GetSpeed write SetSpeed;
end;
procedure TMyClass.SetSpeed(const Value: WideString);
begin
KeyValue['SPEED'] := Value;
end;
function TMyClass.GetSpeed: WideString;
begin
Result := KeyValue['SPEED'];
end;
Upvotes: 2
Reputation: 47714
That is not possible. Indexed properties support Integer as index constants only.
See the documentation (own emphasis):
Index specifiers allow several properties to share the same access method while representing different values. An index specifier consists of the directive
index
followed by an integer constant between-2147483647
and2147483647
. If a property has an index specifier, itsread
andwrite
specifiers must list methods rather than fields.
Upvotes: 6