【问题标题】:"As" operator for constrained generic types受约束的泛型类型的“As”运算符
【发布时间】:2009-08-06 08:59:34
【问题描述】:

考虑:

TTest <T : class, constructor> = class 
public
  function CreateMyObject : T;
end;
function TTest<T>.CreateMyObject : T;
var
  Obj : TObject;
begin
  Obj := T.Create; 
  Result := (Obj as T);
end;

为什么这不可能?编译器为 as 运算符生成“运算符不适用于此类型”错误消息。 T 被限制为类类型,所以这应该可以工作,不是吗?

感谢您的帮助。

【问题讨论】:

  • 没有。那将是无效的类型转换。

标签: delphi generics delphi-2009


【解决方案1】:

我遇到了同样的问题,并通过在类中添加低级指针复制方法作为解决方法:

  TTest <T : class, constructor> = class
  private
    function _ToGeneric(AItem: TObject): T; inline; //inline, so it's a little faster
  public
    function CreateMyObject : T;
  end;

  function TTest<T>.CreateMyObject : T;
  var
    Obj : TObject;
  begin
    Obj := T.Create;
    Result := _ToGeneric(Obj);
  end;

  function TTest<T>._ToGeneric(AItem: TObject): T;
  begin
    System.Move(AItem,Result,SizeOf(AItem))
  end;

【讨论】:

  • +1 这似乎有效!不错的解决方法。我希望这会很快得到解决。
【解决方案2】:

这是使用 Delphi 编译器的a known issue。如果你想看到它被修复,请投票给它。与此同时,你可以通过说来解决它

Result := (Obj as TClass(T));

【讨论】:

  • 嗨梅森!感谢您的提示。不幸的是,您的解决方法无法为我编译(“'(' 预期但 ')' 找到”)
  • 确认!如果这对您的版本不起作用,那么 MvdH 的答案可能是唯一的方法。
【解决方案3】:

不知道为什么它不起作用。我认为泛型实现中仍然存在一些怪癖/错误。

但以下代码有效:

// Class definition
function CreateMyObject<T : class, constructor>  : T;


// Class implementation
function TForm1.CreateMyObject<T>: T;
var
  Obj : T;
begin
  Obj := T.Create;
end;

【讨论】:

  • 是的,这可行,但不幸的是我只能创建一个 TObject,因为我使用 TClass.Create 来创建对象。这是针对工厂课程的(请参阅我最近的其他问题)
  • 为什么不用一个共同的祖先和一个虚拟构造函数呢?你可以创建一个类型的类并使用它(而不是 TClass)?
  • 您能详细解释一下吗?据我了解,这无济于事,因为我希望返回值是 T 类型而不是 TCommonAncestor 类型。
  • 今晚我会回答。然后我有时间测试一下。但是我在使用泛型时遇到了一些死胡同,所以要为最坏的情况做好准备......
猜你喜欢
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-23
  • 2017-01-21
  • 2019-10-02
  • 1970-01-01
相关资源
最近更新 更多