2

我得到E2010 Incompatible types: 'TDerivedFrame' and 'TBaseFrame'以下代码:

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>;

仅使用T.Create(nil)原因E2568 Can't create new instance without CONSTRUCTOR constraint in type parameter declaration

据我所知,您只能使用无参数构造函数创建构造函数约束。

这样做的正确方法是什么?

PS:当我删除变量时代码编译,这让我认为这是编译器错误?!

编辑:我了解 E2010 错误,但即使使用T(TBaseFrame(T).Create(nil))它也不起作用。这会编译,但会在运行时导致访问冲突:

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>,就不会有编译器错误。

AV 是因为您要转换T为实例而不是类。

于 2012-11-12T11:36:04.117 回答
0

尝试使用这个: TContainer<T:constructor, TBaseFrame> = class

于 2013-01-18T08:45:01.927 回答