如何使用字符串索引属性?
我有这样的代码:如何使用字符串索引属性?
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;
的Speed
财产给我的错误:
Incompatible types: 'String' and 'Integer'
我需要的索引是字符串。 是否可以使用带有字符串值的index
?
这是不可能的。索引属性仅支持整数作为索引常量。
见documentation(各有侧重):
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.
这是根本不可能与index
符,因为它仅支持完整的索引。你将不得不使用一个单独的一套属性的getter/setter方法:
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;
它非常好
属性值[常量名称:字符串]:串读的GetValue写的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)
这就是OP在其“KeyValue”属性中显示的内容。 Delphi中的索引说明符有些不同。它允许你为在你通过索引说明符值切换的getter内部的许多属性使用相同的getter和setter。所以这个“工作”并且是由不同语言知道的索引说明符的可能实现,在Delphi中它不是真正的索引说明符用法。答案是你不能将字符串类型与索引说明符一起使用。 – Victoria
你的意思是这样的吗? http://www.delphibasics.co.uk/RTL.asp?Name=Index –
是的,这是真正的索引说明符的用法。许多属性使用相同的getter和setter。在他们的实现中,他们收到索引说明符值,并且他们可以决定如何处理要获取或设置的值。你已经显示的很好,但它不使用索引说明符。 – Victoria
感谢。我已经知道了。但是如果我需要为每个键编写一个setter/getter,那就会忽略属性索引的整个点。无论如何。 – zig