在一些代码中,我正在修复,这大量使用泛型和接口类型,我收到错误
E2134, Type '' has no type info.
我相信这是因为我处于重构的中间,其中一些深度嵌套的单元都使用泛型不同步,但错误不会发生在我可以使用错误消息来修复代码,因为代码在出现错误的位置没有任何问题.
这是上下文,嘲笑,因为我无法发布代码,有太多:
unit GenericThing; ... interface ... type ... IThingListOf= interface( IThingContainer ) function getEnumerator: TEnumerator ; 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 ); 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 ...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"没有类型信息.在我看来,这是一个奇怪的(腋下)Pascal/Delphi,你完全违反了Wirth强烈打字的想法.它与C中的"void*"指针或Delphi中的"Pointer"类型一样弱类型,但它很少使用,除了像标准的pre-object-pascal RTL函数之类的地方,如Move,等等上.在我看来,泛型中使用的接口中的无类型参数应该被允许或禁止,但有时不允许,并且在其他时候不允许.
这是1978年Pascal功能与2009年ObjectPascal功能混合严重的情况.
错误消息表示没有可用于给定类型的类型信息.
这是一个产生消息的最小程序:
type {$M+} IThing = interface procedure P(const X); end; {$M-} begin end.
看起来,问题在于IThingListOf<>
,或者它的一个祖先是用{$M+}
活动编译的.编译器假定您确实需要接口的完整类型信息; 最初它被SOAP等支持用于生成存根等.接口RTTI不支持无类型参数(逻辑上足够,它们不能被SOAP等编组) - 并且它们显示为void类型,并且您最终得到此错误消息.
解决方案是要么不使用{$M+}
- 尽管可能正在使用RTTI,否则它将无法启用 - 或者使用例如,Pointer
而是明确地传递地址.