【问题标题】:How to use property with string index?如何使用带有字符串索引的属性?
【发布时间】:2017-02-21 13:41:52
【问题描述】:

我有这个代码:

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 属性给了我错误:

不兼容的类型:'String' 和 'Integer'

我需要索引是字符串。 是否可以将index 与字符串值一起使用?

【问题讨论】:

    标签: delphi delphi-7


    【解决方案1】:

    这是不可能的。索引属性仅支持 Integer 作为索引常量。

    documentation(自己强调):

    索引说明符允许多个属性共享相同的访问方法,同时表示不同的值。索引说明符由指令index 后跟-21474836472147483647 之间的整数常量组成。如果属性具有索引说明符,则其 readwrite 说明符必须列出方法而不是字段。

    【讨论】:

      【解决方案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;
      

      【讨论】:

      • 谢谢。我已经知道了。但是,如果我需要为每个键编写一个 setter/getter,那将错过属性索引的全部意义。无论如何 +1。
      【解决方案3】:

      效果很好

      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)

      【讨论】:

      • 这就是 OP 在其KeyValue 属性中显示的内容。 Delphi 中的索引说明符有所不同。它允许您对许多属性使用相同的 getter 和 setter,在 getter 内部您可以通过索引说明符值进行切换。因此,这“有效”并且是不同语言已知的索引说明符的可能实现,在 Delphi 中,它不是真正的索引说明符使用。答案是不能将字符串类型与索引说明符一起使用。
      • 你的意思是这样的吗? delphibasics.co.uk/RTL.asp?Name=Index
      • 是的,这就是真正的索引说明符的用法。许多属性使用相同的 getter 和 setter。在他们的实现中,他们接收索引说明符值,并且他们可以决定如何处理要获取或设置的值。您显示的内容很好,但它不使用索引说明符。
      猜你喜欢
      • 2014-12-21
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      • 2016-04-17
      相关资源
      最近更新 更多