インデックス指定子をこのように使っても問題ないでしょうか?


デル太  2006-04-07 08:14:14  No: 20896

TPoint型のプロパティを(X,Y)に分けてInteger型のプロパティとする改造をしました。
すでにTPoint型で正常に動いていたため、アクセスメソッドを増やすことでロジックを変えたくありませんでした。
ヘルプで「複数のプロパティで同じアクセスメソッドを共有できる」という「インデックス指定子」を見つけ、これを利用しました。

ヘルプでの説明は、配列プロパティが例になっています。
そのため、配列プロパティとインデックス指定子を「必ず」ペアで使うような印象を受けました。
最後の4行が(たぶん)配列プロパティの説明なので、間違いなくそんな感じです。

でも「複数のプロパティで同じアクセスメソッドを共有できる」という文面からは配列プロパティと無関係にインデックス指定子を使いたくなります。
そこで、希望と推測で自分なりにコードを考えてみました。
結果として次のコードで期待通りに動いています。(一部省略しています。)

-----
TMyClass = class
private
  FStartX, FStartY: Integer; //始点
  procedure SetStartPoint(Index, Value: Integer); //始点設定
published
  property StartX: Integer index 0 read FStartX write SetStartPoint;
  property StartY: Integer index 1 read FStartY write SetStartPoint;

procedure TLine.SetStartPoint(Index, Value: Integer);
begin
  Case Index of            //←文面から、こう使えたらな・・と思ってこの形にしました
    0: FStartX := Value;
    1: FStartY := Value;
  end;
end;
-----

インデックス指定子を、このように単独(配列プロパティを使わない形)で使っても問題ないでしょうか?

自力でヘルプの読み取りができずに、動きはするがタマタマなのでは?と、とても不安で困っています。
インデックス指定子を使っていらっしゃる方にお願いいたします。
これで問題が出ないものか、ご指導いただけないでしょうか?

ちょっと長くて恐縮ですが、以下にヘルプの内容を引用させてください。
どうぞ、よろしくお願いします。

-----
インデックス指定子

インデックス指定子を使うと,複数のプロパティで同じアクセスメソッドを共有できます。その場合でも,各プロパティは異なる値を表すことができます。インデックス指定子を指定するときは,index 指令の後に -2147483647 〜 2147483647 の範囲の整数定数を指定します。次に例を示します。

type
  TRectangle = class
  private
    FCoordinates: array[0..3] of Longint;
    function GetCoordinate(Index: Integer): Longint;
    procedure SetCoordinate(Index: Integer; Value: Longint);
  public
    property Left: Longint index 0 read GetCoordinate write SetCoordinate;
    property Top: Longint index 1 read GetCoordinate write SetCoordinate;

    property Right: Longint index 2 read GetCoordinate write SetCoordinate;
    property Bottom: Longint index 3 read GetCoordinate write SetCoordinate;
    property Coordinates[Index: Integer]: Longint read GetCoordinate write SetCoordinate;
    ...
end;

インデックス指定子を持つプロパティのアクセスメソッドは,Integer 型の追加の値パラメータを 1 つとる必要があります。この値パラメータは,読み出し関数の場合は最終パラメータとして指定しなければなりません。書き込み手続きの場合は最後から 2 番目のパラメータとして指定しなければなりません(プロパティの値を指定するパラメータを最後に指定)。インデックス指定子を持つプロパティにアクセスすると,プロパティの整数定数がアクセスメソッドに自動的に渡されます。

上記のように宣言されている場合,Rectangle の型が TRectangle 型だとすると,次のコードは,

Rectangle.Right := Rectangle.Left + 100;

次のように記述するのと同等です。

Rectangle.SetCoordinate(2, Rectangle.GetCoordinate(0) + 100);
-----


かみづ  2006-04-07 08:29:20  No: 20897

配列プロパティである必要はありません。
といいますか、引用されている例でも配列プロパティでないと思うのですが・・・


デル太  2006-04-07 08:44:08  No: 20898

かみづさん、さっそくコメントをありがとうございます。
配列プロパティでなくてもいいんですね。ほっとしました。

> 引用されている例でも配列プロパティでないと思うのですが・・・

この点、ご指摘ありがとうございます。
すいません。もっともっと勉強が必要ですね。

配列プロパティの例と見比べて、
-----
配列プロパティの宣言には,インデックスの名前と型を指定するパラメータリストが含まれます。次に例を示します。

property Objects[Index: Integer]: TObject read GetObject write SetObject;
-----

次の行が上の例と同じ配列プロパティだと思ってしまったんです。

> property Coordinates[Index: Integer]: Longint read GetCoordinate write SetCoordinate;

そして、インデックス指定子の説明に配列プロパティが出てくるのは、必須だから・・と誤解していました。

配列プロパティを自由に使えるくらいに勉強します。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加