【问题标题】:Problem with Generics and As Cast [duplicate]泛型和 As Cast 的问题 [重复]
【发布时间】:2011-09-10 23:57:54
【问题描述】:

可能重复:
“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.

如何克服这个编译器错误?

【问题讨论】:

  • 我可以重现这个; as cast 编译失败,出现“不兼容的类型”错误。现在,问题是什么? :-) 顺便说一句,as 演员表似乎是多余的。您可以安全地硬播T(FCtrl),因为T 被限制为TControl(或后代)。
  • @TOndrej:问题是:为什么会失败?它是编译器错误吗?
  • 是的,我个人认为这是一个编译器错误。演员应该成功似乎是合乎逻辑的。此外,编译器具有验证此类转换所需的知识。

标签: delphi generics casting delphi-xe


【解决方案1】:

这是一个已知问题:"As" operator for constrained generic types

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

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

【讨论】:

  • 我发布了一个简化的摘录。基本上我们需要在使用基本类型时访问控件,但在使用派生类型时希望获得专门的控件而不进行强制转换。
  • 刚刚意识到我自己问了你链接到的问题:) 已经太晚了......
  • 我上面的代码将允许所有这些。
  • Aww 为您发布的不仅是重复的,而且是您自己的问题的重复而感到羞耻! ;-)
  • 问题是TControlWrapper &lt;TEdit&gt;TControlWrapper &lt;TComboBox&gt;没有共同的基类。通过让泛型TControlWrapper&lt;T&gt; 继承自TControlWrapper 并在那里公开TControl,我们可以使用所有使用通用基类型的控件包装器。
【解决方案2】:

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

不幸的是,编译器没有 足够聪明地找出一个 类类型约束意味着 T 是 保证与一个相同的大小 指针。

【讨论】:

  • 实际上,我们现在有同一个问题的 3 个版本,都是由 @Smasher 提出的。哇!
  • 嗯,是的,我应该更仔细地搜索。但另一方面,这些事情在两年多的时间里没有得到解决,这不是我的错。顺便说一句:Mason Wheeler 在重复问题中发布的 QC 报告已关闭为固定...
  • 这几乎是同一个问题?这甚至不是相同的编译器错误。对于泛型中的所有错误(至少在 2009 年,并且显然仍在 XE 中),这些细微的差异确实很重要。
猜你喜欢
  • 1970-01-01
  • 2017-01-15
  • 1970-01-01
  • 1970-01-01
  • 2011-08-23
  • 1970-01-01
  • 2015-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多