是否可以在Delphi中为泛型类创建类型别名

RM.*_*RM. 11 delphi generics alias types declaration

我想为泛型类定义类类型(类型别名).我想这样做,因此单元b的用户可以访问TMyType而无需使用单元a.我有这样的单位:

unit a;
interface
type
  TMyNormalObject = class
    FData: Integer;
  end;
  TMyType<T> = class
    FData: <T>;
  end;
implementation
end.

unit b;
interface
type
  TMyNormalObject = a.TMyNormalObject;  // works
  TMyType<T> = a.TMyType<T>; // E2508 type parameters not allowed on this type
implementation
end.
Run Code Online (Sandbox Code Playgroud)

我已经找到了一个我不喜欢的可能的解决方法,因为它可以引入很难找到错误:

TMyType<T> = class(a.TMyType<T>); 
Run Code Online (Sandbox Code Playgroud)

这种方法的问题在于它引入了一个新的类类型,而a.TMyType实例不是b.TMyType(而a.TMyNormallClass是b.TMyNormalClass,反之亦然 - 它们指的是同一个类).

LU *_* RD 11

这是目前还没有可以声明一个类类型,泛型类.

有关更多信息,请参阅QC76605.还有下面的更新.

示例:

TMyClass<T> = class
end;
TMyClassClass<T> = class of TMyClass<T>; //E2508 type parameters not allowed on this type
Run Code Online (Sandbox Code Playgroud)

显示的解决方法如下所示:

TMyIntClass = TMyType<Integer>;
TMyIntClassClass = Class of TMyIntClass;
Run Code Online (Sandbox Code Playgroud)

但是如评论那样,这将破坏泛型的整个概念,因为类必须为每个泛型实例化进行子类化.

这里还有一个关于生成泛型类型的专用子类的类似解决方法的链接:derive-from-specialized-generic-types.在这种情况下,它看起来像这样:

TMySpecialClass = Class(TMyType<Integer>);
Run Code Online (Sandbox Code Playgroud)

更新:

RM提出的解决方法:

TMyType<T> = class(a.TMyType<T>);
Run Code Online (Sandbox Code Playgroud)

可以使用以下方案实现类型安全:

unit Unita;
interface
type
  TMyType<T> = class
    Constructor Create;
  end;

implementation

uses
  Unitb;

constructor TMyType<T>.Create;
begin
  Inherited Create;
  //WriteLn( Self.QualifiedClassName,' ',Unitb.TMyType<T>.QualifiedClassName);
  Assert(Self.QualifiedClassName = Unitb.TMyType<T>.QualifiedClassName);
end;

end.
Run Code Online (Sandbox Code Playgroud)
unit Unitb;

interface

uses Unita;

type
  TMyType<T> = class(Unita.TMyType<T>);
implementation
end.
Run Code Online (Sandbox Code Playgroud)
Project Test;
{$APPTYPE CONSOLE}    
uses
  System.SysUtils,
  Unita in 'Unita.pas',
  Unitb in 'Unitb.pas';

var
  t1 : Unita.TMyType<Integer>;
  t2 : Unitb.TMyType<Integer>;
  t3 : TMyType<Integer>;    
begin
  try
    //t1 := Unita.TMyType<Integer>.Create;  //Exception EAssertionFailed !!
    t2 := Unitb.TMyType<Integer>.Create;
    t3 := TMyType<Integer>.Create;
    ReadLn;
  finally
    //t1.Free;
    t2.Free;
    t3.Free;
  end;
end.
Run Code Online (Sandbox Code Playgroud)

创建泛型类时,将进行测试以检查创建的类是否从单元b中声明的类型派生.从而检测到从单元a创建该类的所有尝试.

更新2:

为了清楚起见,对泛型类的引用" class of type<T>"是不可能的,但泛型类的副本很好.