8.6 Type compatibility

Whenever a generic class is specialized, this results in a new, distinct type. These types are assignment compatible if the same template types are used.

Take the following generic definition:

{$mode objfpc}
unit ua;

interface

type
  Generic TMyClass<T> = Class(TObject)
    Procedure DoSomething(A : T; B : INteger);
  end;

Implementation

Procedure TMyClass.DoSomething(A : T; B : Integer);

begin
  // Some code.
end;

end.

And the following specializations:

{$mode objfpc}
unit ub;

interface

uses ua;

Type
  TB = Specialize TMyClass<string>;

implementation

end.

the following specializations is identical, but appears in a different unit:

{$mode objfpc}
unit uc;

interface

uses ua;

Type
  TB = Specialize TMyClass<string>;

implementation

end.

The following will then compile:

{$mode objfpc}
unit ud;

interface

uses ua,ub,uc;

Var
  B : ub.TB;
  C : uc.TB;

implementation

begin
  B:=C;
end.

The types ub.TB and uc.TB are assignment compatible. It does not matter that the types are defined in different units. They could be defined in the same unit as well:

{$mode objfpc}
unit ue;

interface

uses ua;

Type
  TB = Specialize TMyClass<string>;
  TC = Specialize TMyClass<string>;


Var
  B : TB;
  C : TC;

implementation

begin
  B:=C;
end.

Each specialization of a generic class with the same types as parameters is a new, distinct type, but these types are assignment compatible if the template types used to specialize them are equal.

If the specialization is with a different template type, the types are still distinct, but no longer assignment compatible. i. e. the following will not compile:

{$mode objfpc}
unit uf;

interface

uses ua;

Type
  TB = Specialize TMyClass<string>;
  TC = Specialize TMyClass<integer>;


Var
  B : TB;
  C : TC;

implementation

begin
  B:=C;
end.

When compiling, an error will result:

Error: Incompatible types: got "TMyClass<System.LongInt>"
                           expected "TMyClass<System.ShortString>"