8.6 Совместимость типов

Вверх  Предыдущий  Следующий

Специализация дженерика всегда приводит к новому типу. Эти типы совместимы по присваиванию, если используют один и тот же шаблон типов.

Возьмем следующее определение дженерика:

{$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

   // какой-то код

end;

 

end.

И следующие специализации:

{$mode objfpc}

unit ub;

 

interface

 

uses ua;

 

Type

   TB = Specialize TMyClass<string>;

 

implementation

 

end.

Идентичную специализацию, но описанную в другом модуле:

{$mode objfpc}

unit uc;

 

interface

 

uses ua;

 

Type

   TB = Specialize TMyClass<string>;

 

implementation

 

end.

Код ниже будет скомпилирован:

{$mode objfpc}

unit ud;

 

interface

 

uses ua,ub,uc;

 

Var

   B : ub.TB;

   C : uc.TB;

 

implementation

 

begin

   B:=C;

end.

Типы ub.TB и uc.TB совместимы по присваиванию. Не важно, что эти типы описаны в различных модулях. Можно их описать и в одном модуле:

{$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.

Каждая специализация дженерика классов, с теми же типами в качестве параметров является новым, особым типом, но эти типы совместимы по присваиванию, если типы шаблонов, используемых для их специализации равны.

Если специализация является типом с другим шаблоном, типы по-прежнему различны и не совместимы по присваиванию. А значит следующий код не будет компилироваться:

{$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.

При компиляции возникнет ошибка:

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

Ошибка: Типы несовместимы: получен "TMyClass <System.LongInt>" вместо"TMyClass <System.ShortString>"