2017-02-21 4 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

Это невозможно. Индексированные свойства поддерживают Integer только как константы индекса.

См 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 спецификатором, поскольку он поддерживает только интегральные индексы. Вам придется использовать отдельный набор свойств методов геттер/сеттер:

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

Спасибо. Я уже знаю, что. но это пропускает всю точку индекса свойств, если мне нужно написать сеттер/получатель для каждого ключа. +1 в любом случае. – 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 и setter для многих свойств, где внутри получателя вы переключаетесь по значению спецификатора индекса. Так что это «работает» и является возможной реализацией спецификатора индекса, известного на разных языках, в Delphi это не использование реального индексатора. Ответ заключается в том, что вы не можете использовать строковый тип с указателем индекса. – Victoria

+0

Вы имеете в виду что-то вроде этого? http://www.delphibasics.co.uk/RTL.asp?Name=Index –

+1

Да, это использование реального указателя индекса. Многие свойства используют один и тот же геттер и сеттер. В своей реализации они получают значение спецификатора индекса, и они могут решить, что делать со значением, которое нужно получить или установить. То, что вы показали, хорошо, но не использует спецификатор индекса. – Victoria

Смежные вопросы