以下简化的示例代码在尝试使用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.
如何克服此编译器错误?
答案 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相同 指针。