В некотором коде, который я исправляю, который интенсивно использует обобщенные и сопряженные типы, я получаю ошибку
E2134, Type '<void>' has no type info.
Я полагаю, что это потому, что я в середине рефакторинга, где какой-то глубоко вложенный набор модулей, которые все используют дженерики, не синхронизирован, но ошибка не происходит в месте, где я могу использовать сообщение об ошибке, чтобы исправить код, потому что в этом нет ничего плохого с кодом, в месте, где появляется ошибка.
Вот контекст, смоделированный, потому что я не могу опубликовать код, слишком много:
unit GenericThing;
...
interface
...
type
...
IThingListOf<ThingT> = interface( IThingContainer )
function getEnumerator: TEnumerator<ThingT>;
function getCount: Integer;
function getThing( Index: integer ): ThingT;
function getFirst: ThingT;
function IndexOf( value: ThingT): integer;
function addItem( const Thing: ThingT ): ThingT;
function removeItem( const Thing: ThingT ): Integer;
procedure clear;
procedure Sort; overload;
procedure Sort(const AComparer: IComparer<ThingT>); overload;
property Count: integer read getCount;
property First: ThingT read getFirst;
property Items[Index: integer]: ThingT read getThing; default;
end;
// error appears on whatever line number comes after the declaration of IThingListOf<ThingT>...end;
function AnythingYouLikeHere:Integer; // there is nothign wrong with this line, but you get the E2134 here.
Похоже, что проблема в самом IThingContainer:
IThingContainer = interface ...
...
procedure DoSomething(const Param);
end;
Выше "const Param" не имеет информации о типе. На мой взгляд, это странная (подмышка) Паскаля / Дельфи, когда вы полностью нарушаете идею Вирта о строгой типизации. Он примерно так же слабо типизирован, как указатель «void *» в C или тип «Pointer» в Delphi, но он используется редко, кроме как в местах, подобных стандартным функциям RTL пред-объектного паскаля, таких как Move и т. Д. на. По моему мнению, нетипизированные параметры в интерфейсах, используемые в обобщениях, должны быть либо разрешены, либо запрещены, но иногда не разрешены, но и запрещены в других случаях.
Это случай, когда функция Pascal 1978 года плохо смешивалась с функцией ObjectPascal. с 2009 года.
Сообщение об ошибке означает, что информация о типе для данного типа недоступна.
Вот минимальная программа, которая выдает сообщение:
type
{$M+}
IThing = interface
procedure P(const X);
end;
{$M-}
begin
end.
Проблема, похоже, в том, что IThingListOf <>
или один из его предков был скомпилирован с помощью {$ M +}
активен. Из этого компилятор предполагает, что вам действительно нужна полная информация о типе интерфейса; изначально он использовался поддержкой SOAP и т. д. для создания заглушек и т. д. Интерфейс RTTI не поддерживает нетипизированные параметры (достаточно логично, они не могут быть упорядочены с помощью SOAP и т. д.) - и они отображаются как имеющие тип void, и вы получите это сообщение об ошибке.
Решение состоит в том, чтобы либо не использовать {$ M +}
- хотя предположительно используется RTTI, иначе он не был бы включен - либо использовать, например, Указатель
вместо него и явная передача адреса.
Из этого трудно сказать, особенно без определения IThingContainer. Если вы закомментируете определение интерфейса, будет ли он компилироваться после этого? Очевидно, что он сломается, когда вы попытаетесь создать класс, реализующий интерфейс, но устранит ли его комментирование эту проблему?
Если да, то компилятор подавился чем-то в определении интерфейса. Попробуйте закомментировать его часть, чтобы понять, где проблема. Если нет, то придется искать в другом месте.