“As” operator for constrained generic types

Deadly 提交于 2019-12-01 06:50:28

问题


Consider:

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;

Why isn't this possible? Compiler yields an "Operator not applicable to this type" error message for the as operator. T is constrained to be a class type, so this should work, shouldn't it?

Thanks for the help.


回答1:


I ran into the same problem and solved it by adding a low-level pointer-copy method to the class as a workaround:

  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;



回答2:


This is a known issue with the Delphi compiler. Please vote for it if you'd like to see it fixed. In the meantime, you can work around it by saying

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



回答3:


Not sure why it doesn't work. I assume there are still some quirks/bugs in the generics implementation.

But the following code works:

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


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


来源:https://stackoverflow.com/questions/1237740/as-operator-for-constrained-generic-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!