9

基本オブジェクト クラスのサブクラスを保持するように設計されたカスタム TObjectList 子孫を作成しました。次のようになります。

interface
   TMyDataList<T: TBaseDatafile> = class(TObjectList<TBaseDatafile>)
   public
      constructor Create;
      procedure upload(db: TDataSet);
   end;

implementation

constructor TMyDataList<T>.Create;
begin
   inherited Create(true);
   self.Add(T.Create);
end;

新しいリストはそれぞれ、空白のオブジェクトが 1 つで始まるようにしたいと考えています。とても簡単ですよね?しかし、コンパイラはそれを好まない。それは言います:

「型パラメーター宣言でコンストラクター制約なしで新しいインスタンスを作成できません」これはジェネリック関連のものであるとしか思えません。何が起こっているのか、このコンストラクターを機能させる方法を知っている人はいますか?

4

2 に答える 2

17

Tviaのインスタンスを作成しようとしていますT.Create。ジェネリック型にパラメーターなしのコンストラクターがあることをコンパイラーが認識しないため、これは機能しません (注意: これは必須ではありません)。これを修正するには、次のようなコンストラクター制約を作成する必要があります。

<T: constructor>

または、特定のケースでは:

<T: TBaseDatafile, constructor>
于 2008-12-20T20:23:31.897 に答える
2

古い質問への簡単な更新..

コンストラクターの制約は必要ありません。また、このような RTTI を使用して (XE2 で RTTI または System.RTTI を使用して)、オブジェクトのパラメーターでこれを行うこともできます。

constructor TMyDataList<T>.Create;
var
  ctx: TRttiContext;
begin
   inherited Create(true);
   self.Add(
     ctx.
     GetType(TClass(T)).
     GetMethod('create').
     Invoke(TClass(T),[]).AsType<T>
   );
end;

パラメータがある場合は、このように追加するだけです

constructor TMyDataList<T>.Create;
var
  ctx: TRttiContext;
begin
   inherited Create(true);
   self.Add(
     ctx.
     GetType(TClass(T)).
     GetMethod('create').
     Invoke(TClass(T),[TValue.From('Test'),TValue.From(42)]).AsType<T>
   );
end;
于 2011-09-04T20:04:55.423 に答える