3
type
  TForm72 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }    
  end;

  TTestForm = class(TForm)
  public
    constructor CreateTest(AOwner: TComponent); virtual;
  end;

  TTestForm1 = class(TTestForm)    
  public
    constructor CreateTest(AOwner: TComponent); override;
  end;

  TTest<T: TTestForm, constructor> = class(TObject)
  public
    class procedure Test;
  end;

var
  Form72: TForm72;

implementation

{$R *.dfm}

procedure TForm72.FormCreate(Sender: TObject);
begin
  TTest<TTestForm1>.Test;
end;

{ TTest<T> }

class procedure TTest<T>.Test;
var
  F: T;
begin
  F := T.CreateTest(Application);
  Form72.Caption :=  F.Name;
end;

{ TTestForm }

constructor TTestForm.CreateTest(AOwner: TComponent);
begin
  inherited Create(AOwner);
end;

{ TTestForm1 }

constructor TTestForm1.CreateTest(AOwner: TComponent);
begin
  inherited;
  Caption := 'Bang';
end;

end.

このコードはXE2でコンパイルされましたが、XE3の「[dcc32エラー] Unit71.pas(55):E2010互換性のないタイプ:'T'および'プロシージャ、型なしポインタ、または型なしパラメータ'」で失敗します。私が間違ったこと、またはコンパイラが間違ったことはありますか?

4

1 に答える 1

4

実際、このコードはXE2のコンパイラのバグを強調しています。XE2では、コードはコンパイルされるべきではないときにコンパイルされます。制約を削除するconstructorと、コンパイルは失敗します

E2568タイプにCONSTRUCTOR制約がないと新しいインスタンスを作成できません
パラメータ宣言

ただし、constructor制約は、クラスにパラメーターのないコンストラクターがあることを示しているだけです。ドキュメントには次のように記載されています。

コンストラクターの制約

タイプパラメータは、予約語「コンストラクタ」のゼロまたは1つのインスタンスによって制約される場合があります。つまり、実際の引数タイプは、デフォルトコンストラクター(パブリックパラメーターなしコンストラクター)を定義するクラスである必要があります。これにより、ジェネリック型内のメソッドは、引数について何も知らなくても、引数タイプのデフォルトコンストラクターを使用して引数タイプのインスタンスを構築できます。タイプ自体(最小基本タイプ要件なし)。

制約の存在またはその他がconstructorこのコードに影響を与えるという事実は、XE2コンパイラに障害があることを示しています。


XE3では、コードは正しくコンパイルに失敗します。構文を使用してコンストラクターを呼び出す唯一の方法は、制約をT.Create使用していて、パラメーターなしのコンストラクターを呼び出す場合です。constructorここではそうではないため、XE3はコンパイルエラーを正しく報告します。

コンパイルするにはキャストが必要です。

F := T(TTestForm(T).CreateTest(Application));

これは、Delphiジェネリック実装のコンストラクターの処理の癖のいくつかを回避するためのよく知られたトリックです。面倒に見えますが、このコードは言語設計者が私たちに使用することを意図したものだと思います。私の意見では、動作の変更はバグ修正によるものであり、XE3は設計どおりに動作しています。

于 2012-10-05T15:35:22.910 に答える