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>"