#delphi #generics #interface
#delphi #обобщения #интерфейс
Вопрос:
Следующий код Delphi не компилируется с ошибкой в функции Foo, но функция Foo2 компилируется. Это сводит меня с ума, у кого-нибудь есть идея?
type
IA<T> = Interface
end;
TA<T> = class(TInterfacedObject, IA<T>)
function Foo<V> : IA<V>;
end;
TB<U,T> = class(TA<T>)
end;
TC = class
function Foo2<T,V> : IA<V>;
end;
implementation
{ TA<T> }
function TA<T>.Foo<V>: IA<V>;
begin
Result := TB<T,V>.Create;
end;
{ TC }
function TC.Foo2<T,V>: IA<V>;
begin
Result := TB<T,V>.Create;
end;
Ответ №1:
Это действительно выглядит странно, и я подозреваю, что это ошибка. Вы можете обойти это, объявив, что TB<U, T>
реализует IA<T>
. Изменить
TB<U, T> = class(TA<T>)
Для
TB<U, T> = class(TA<T>, IA<T>)
Обратите внимание, что ваш код со всеми удаленными дженериками компилируется:
type
IA = interface
end;
TA = class(TInterfacedObject, IA)
function Foo: IA;
end;
TB = class(TA)
end;
TC = class
function Foo2: IA;
end;
function TA.Foo: IA;
begin
Result := TB.Create;
end;
function TC.Foo2: IA;
begin
Result := TB.Create;
end;
Это, по-видимому, подтверждает мою уверенность в том, что ваш код правильный и должен быть принят компилятором.
Комментарии:
1. Спасибо за ответ, но почему Foo2 работает без изменения объявления?
2. Как я уже сказал, для меня это выглядит как ошибка
3. Я думаю, это потому, что Foo2 явно ссылается на интерфейс. Foo on ссылается косвенно через класс TA, и поэтому необходимо указать TB, который реализует интерфейс.
4. @Dsm Я не понимаю. Тип, возвращаемый двумя функциями, идентичен, и код в двух функциях идентичен.
5. @DavidHeffernan Я знаю, но я видел похожие проблемы, о которых сообщалось на этом сайте, и это было причиной. Я думаю, что это по замыслу, возможно, безопасность превыше всего, если вы неявно используете интерфейс (через наследование), тогда вы должны объявить этот интерфейс в классе, который его использует.