2009-02-27 8 views
5
type 
    TStaticArray = array[1..10] of integer; 
    TDynamicArray = array of integer; 

    TMyClass = class(TObject) 
    private 
     FStaticArray: TStaticArray; 
     FDynamicArray: TDynamicArray; 
    published 
     property staticArray: TStaticArray read FStaticArray write FStaticArray; //compiler chokes on this 
     property dynamicArray: TDynamicArray read FDynamicArray write FDynamicArray; //compiler accepts this one just fine 
    end; 

ここでは何が起こっていますか?静的配列はエラーを示します。 "publishedプロパティ 'staticArray'はARRAY型ではありませんが、動的配列は問題ありませんか?よくわかりません。誰もがこれの背後にある推論を知っている、と私はそれを回避することができますか? (そして、いいえ、私はすべての静的配列を動的なものとして再宣言したくないのですが、それは理由のためにサイズになっています)一部の配列は公開できますが、他の配列は公開できないのはなぜですか?

答えて

6

を見てみ公開宣言は、仮想メソッドテーブルに情報を格納するようにコンパイラーに指示します。特定の種類の情報のみを保存することができます。
パブリッシュされたプロパティの型は、ポインタ、レコード、または配列にすることはできません。設定されたタイプの場合は、整数で格納できるほど小さくなければなりません。
(オレリー、デルフト、ナルトヘル)

+3

ただ1つの精度:レコードを公開プロパティとして使用することはできません。実際には許可されていますが、このフィールドにはRTTIは付けられていません。したがって、公開されたプロパティのセクションにレコードを追加することは無意味です。一方、動的配列はRTTI内で許可され、処理されます。 –

-3

配列プロパティは公開できません。 したがって、次のコードは機能しません。回避策はおそらくそれをpublicにすることです。

TMyClass = class(TObject) 
    private 
    FStaticArray: TStaticArray; 

    function GetFoo(Index: Integer): Integer; 
    procedure SetFoo(Index: Integer; Value: Integer); 
    public 
    property Foo[Index: Integer] : Integer read GetFoo write SetFoo; 
    end; 
+0

いいえ。それはどちらもうまくいかない。同じエラー。 –

+0

TStaticArrayをプロパティとして使用せずに同じエラーをどのように得ることができますか? –

+0

upvoted downvote。 –

0

動的配列プロパティをパブリッシュできる理由は、動的配列が参照、つまり「暗黙的にポインタ」として実装されているためです。彼らは本当に文字列のように動作します。

スタティックアレイを公開できない理由はわかりません。それは、それが作られているだけの方法ですが、私は配列がどのように動作するかダイナミックの詳細については。..

を推測し、DrBobs site

0

ゲッターとセッターが必要です。 D2009(他のバージョンをチェックしていない)では、何らかの理由でgetters/setterのパラメータをconstにすることはできません。 ?

これは、D2009の下で正常に動作します:

type 
    TMyArray = array[0..20] of string; 

type 
    TMyClass=class(TObject) 
    private 
    FMyArray: TMyArray; 
    function GetItem(Index: Integer): String; 
    procedure SetItem(Index: Integer; Value: string); 
    public 
    property Items[Index: Integer]: string read GetItem write SetItem; 
    end; 

implementation 

function TMyClass.GetItem(Index: Integer): string; 
begin 
    Result := ''; 
    if (Index > -1) and (Index < Length(FMyArray)) then 
    Result := FMyArray[Index]; 
end; 

procedure TMyClass.SetItem(Index: Integer; Value: string); 
begin 
    if (Index > -1) and (Index < Length(FMyArray)) then 
    FMyArray[Index] := Value; 
end; 

注:私は一般的にちょうど明らかに、範囲外のインデックス値を無視しないでしょう。これは、クラス定義で静的配列プロパティを作成する方法の簡単な例でした。 IOW、それはコンパイル可能な例です。

1
TMyClass = class(TObject) 
    private 
    FStaticArray: TStaticArray; 
    FIdx: Integer; 
    function GetFoo(Index: Integer): Integer; 
    procedure SetFoo(Index: Integer; Value: Integer); 
    public 
    property Foo[Index: Integer] : Integer read GetFoo write SetFoo; 
    published 
    property Idx: Integer read fidx write fidx; 
    property AFoo: Integer read GetAFoo writte SetAFoo; 
    end; 
implementation 
function TMyClass.GetAFoo: Integer; 
begin 
    result := FStaticArray[FIdx]; 
end; 
procedure TMyClass.SetAFoo(Value: Integer); 
begin 
    FStaticArray[FIdx] := Value; 
end; 
+1

これは* WHY *については何も教えてくれません。 –

関連する問題