3

以下の構造を使用して、コレクションを格納するために TAnimalCollection クラスを定義するにはどうすればよいですか? SelectAll または SelectTop10 を呼び出すと、SelectedRecords が更新されます。private フィールドを削除すると、コードをコンパイルできますが、返された結果セットを格納するメカニズムはありません。

  TDog = class
  private
    FBreed: string;
  public
    property Breed: string read FBreed write FBreed;
  end;

  TCat = class
  private
    IsWild: string;
  public
    property IsWild: string read FIsWild write FIsWild;
  end;

  TMyArray<T> = array of T;

  TAnimalCollection = class
  private
    SelectedRecords: TMyArray<T>; // Generates: Undeclared Identifier: 'T'
  public
    function SelectAll<T>: TMyArray<T>;
    function SelectTop10<T>: TMyArray<T>; 
    // Other Methods
  end;
4

1 に答える 1

6

まず、必要ありませんTMyArray; 組み込みTArray型は同じことを行います。

ただし、コンパイラは正しいです。フィールド宣言には、T. ジェネリック引数は、宣言の右側で使用する前に、宣言の左側に導入する必要があります。Delphi がジェネリック フィールドをサポートしている場合、宣言は次のようになります。

SelectedRecords<T>: TArray<T>;

しかし、そうではありません。とにかく、この場合はそうしたくありません。どうやら、まったく関係のない 2 つのクラスを同じ配列に同時に格納する必要があるようです。配列は常に単一の型です。TDogとを統合する唯一の型TCatTObjectであるため、配列はその型である必要があります。

SelectedRecords: TArray<TObject>;
// or, more conventionally,
SelectedRecords: array of TObject;

「ジェネリック配列」を宣言しても構いませんが、ジェネリック クラスのフィールドまたはジェネリック メソッドの変数としてのみ宣言してください。スタンドアロンのジェネリック配列を宣言できる場合は、配列要素の実際の型がいつ決定されるかを考えてみてください。配列を宣言する時点ではない場合、いつですか? クラスとメソッドでは、クラスの変数を宣言するとき、クラスをインスタンス化するとき、またはメソッドを呼び出すときに、型引数を指定します。これらは宣言とは別の用途であり、それぞれの用途は異なります。変数を宣言するときは、宣言したのと同じ方法で使用する必要があります。変数の型は、プログラムを再コンパイルしないと変更できません。

于 2012-06-06T04:45:52.517 に答える