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