2

I get E2010 Incompatible types: 'TDerivedFrame' and 'TBaseFrame' on the following code:

type
  TBaseFrame = class(TFrame)
  end;

  TDerivedFrame = class(TBaseFrame)
  end;

  TContainer<T: TBaseFrame> = class
  private
    FFrame: T;
  public
    property Frame: T read FFrame;
    constructor Create;
  end;

constructor TContainer<T>.Create;
begin
  inherited;
  FFrame := TBaseFrame(T).Create(nil);
end;

var
  FTab: TContainer<TDerivedFrame>;

Using only T.Create(nil) causes E2568 Can't create new instance without CONSTRUCTOR constraint in type parameter declaration.

As far as I know you can only create a constructor constraint with a parameterless constructor.

What is the correct way to do this?

PS: The code compiles when I remove the variable which makes me think this is a compiler error?!

Edit: I understand the E2010 error, but even with T(TBaseFrame(T).Create(nil)) it doesn't work. This compiles, but causes an access violation at runtime:

type
  TBaseFrame = class(TFrame)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TDerivedFrame = class(TBaseFrame)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TContainer<T: TBaseFrame> = class
  private
    FFrame: T;
  public
    property Frame: T read FFrame;
    constructor Create;
  end;


constructor TBaseFrame.Create(AOwner: TComponent);
begin
  inherited;

end;

constructor TDerivedFrame.Create(AOwner: TComponent);
begin
  inherited;

end;

constructor TContainer<T>.Create;
begin
  inherited;
  FFrame := T(TBaseFrame(T).Create(nil));
end;

var
  FTab: TContainer<TDerivedFrame>;
begin
  FTab := TContainer<TDerivedFrame>.Create;
end.
4

2 に答える 2

4
FFrame := T(TBaseFrameClass(T).Create(nil));

これを行う正しい方法です。

あなたは必要になるでしょう

type 
  TBaseFrameClass = class of TBaseFrame;

コンパイラ エラーは、型をインスタンス化TContainer<TDerivedFrame>しているためです。その型をインスタンス化するとき、コンパイラに処理を依頼します

FFrame := TBaseFrame(...);

はどこFFrameですかTDerivedFrame。ジェネリックなしでそのコードを書き出すと、コンパイラ エラーを理解できます。

したがって、コンパイラはここで正しく動作していますが、インスタンス化の問題が原因です。コンパイラ エラーが明らかになるのは、インスタンス化の時点だけです。インスタンス化がなければ、インスタンス化した場合、TContainer<TBaseFrame>コンパイラ エラーは発生しません。

TAV は、クラスではなくインスタンスにキャストしたためです。

于 2012-11-12T11:36:04.117 に答える
0

これを使用してみてください: TContainer<T:constructor, TBaseFrame> = class

于 2013-01-18T08:45:01.927 に答える