У меня есть интерфейс

IMyInterface<T>

И класс

TMyClass<T>

И теперь я хочу, чтобы я мог передавать только классы в TMyClass как тип, который также реализует IMyInterface.

Сначала я попробовал

TMyClass<T:IMyInterface<T>>

Но, как и ожидалось, теперь компилятор хочет, чтобы я дал ему тип, который реализует интерфейс с типом самого класса, который реализует интерфейс

Вторая попытка была

TMyClass<D,T:IMyInterface<D>> 

Где я думал, D будет общим DataType, который будут использовать TMyInterface и TMyClass.

Итак, после объявления класса, реализующего интерфейс

TMyIntegerClass = class(TInterfacedObject,IMyInterface<Integer>)

Декларация

GMyClass:TMyClass<Integer,TMyIntegerClass>

Не удалось с ошибкой компилятора:

E2514 Type parameter 'D' must support interface 'IMyInterface<System.Integer>' 

Есть указатели?

0
Art1st 17 Фев 2018 в 18:33

1 ответ

Лучший ответ

Это компилируется в Delphi 10.2.2 Tokyo:

type
  IMyInterface<T> = interface
  ['{F810B6BC-78F7-4026-BA83-70435150B758}']
  end;

  TMyClass<D; T: IMyInterface<D>> = class // note the semicolon!
  end;

  TMyIntegerClass = class(TInterfacedObject, IMyInterface<Integer>)
  end;

var
  GMyClass: TMyClass<Integer, TMyIntegerClass>;

Если в объявлении класса я использую <D, T: TSomeType> (запятая!), То оба D и T объявляются одинаковыми type , как параметры функции:

procedure Blah(D, T: TSomeType);

Параметры D и T одного типа, то есть TSomeType .

Теперь, если вы передадите Integer для D, вы получите ошибку, аналогичную той, которую вы получили. Компилятор ожидает два параметра TSomeType.

Но если я использую <D; T: TSomeType>, то D и T являются отдельными типами , т.е. D имеет неизвестный тип, а T - типа TSomeType. Итак, теперь D не объявлен как TSomeType, и если вы передадите Integer, ошибки не будет.

Да, и это тоже задокументировано.

4
Rudy Velthuis 17 Фев 2018 в 21:39