泛型和As Cast的问题

时间:2011-06-08 15:26:10

标签: delphi generics casting delphi-xe

  

可能重复:
  “As” operator for constrained generic types

以下简化的示例代码在尝试使用as运算符强制转换为泛型类型时会产生编译器错误。奇怪的是,is运算符和硬强制转换的组合确实可以正常工作。

program Project8;

{$APPTYPE CONSOLE}

uses
  SysUtils, Controls, StdCtrls;

type
  TControlWrapperBase = class
  protected
    FCtrl : TControl;
  public
    constructor Create (Ctrl : TControl);
  end;

  TControlWrapper <T : TControl> = class (TControlWrapperBase)
  public
    function GetControl : T;
  end;


constructor TControlWrapperBase.Create(Ctrl : TControl);
begin
FCtrl := Ctrl;
end;


function TControlWrapper <T>.GetControl : T;
begin
Result := FCtrl as T;     // does not compile: E2010 Incompatible Types: TEdit and TControl

if FCtrl is T then        // this does work
  Result := T (FCtrl);
end;

var
  Wrapper : TControlWrapper <TEdit>;
  MyCtl   : TEdit;

begin
try
  MyCtl := TEdit.Create(nil);
  TControlWrapper <TEdit>.Create (MyCtl).GetControl;
except
  on E: Exception do
    Writeln(E.ClassName, ': ', E.Message);
end;

end.

如何克服此编译器错误?

2 个答案:

答案 0 :(得分:1)

这是一个众所周知的问题:"As" operator for constrained generic types

但是,我不明白为什么你不能这样写:

type
  TControlWrapper<T: TControl> = class
  private
    FCtrl: T;
  public
    property Ctrl: T read FCtrl;
  end;

答案 1 :(得分:1)

两年多前你已经问过the same question。我不知道从那时起Delphi泛型有什么变化,但可能Barry Kelly的答案仍然有效 - 编译器不能对泛型进行类型转换,因为

  

不幸的是,编译器不是   聪明到足以弄明白了   class-type约束意味着T是   保证与a相同   指针。