2017-02-21 48 views
2

我有這樣的代碼:如何使用字符串索引屬性?

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

回答

6

這是不可能的。索引屬性僅支持整數作爲索引常量。

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 and 2147483647. If a property has an index specifier, its read and write specifiers must list methods rather than fields.

2

這是根本不可能與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; 
+1

感謝。我已經知道了。但是如果我需要爲每個鍵編寫一個setter/getter,那就會忽略屬性索引的整個點。無論如何。 – zig

0

它非常好

屬性值[常量名稱:字符串]:串讀的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)

+3

這就是OP在其「KeyValue」屬性中顯示的內容。 Delphi中的索引說明符有些不同。它允許你爲在你通過索引說明符值切換的getter內部的許多屬性使用相同的getter和setter。所以這個「工作」並且是由不同語言知道的索引說明符的可能實現,在Delphi中它不是真正的索引說明符用法。答案是你不能將字符串類型與索引說明符一起使用。 – Victoria

+0

你的意思是這樣的嗎? http://www.delphibasics.co.uk/RTL.asp?Name=Index –

+1

是的,這是真正的索引說明符的用法。許多屬性使用相同的getter和setter。在他們的實現中,他們收到索引說明符值,並且他們可以決定如何處理要獲取或設置的值。你已經顯示的很好,但它不使用索引說明符。 – Victoria