Delphi编译错误E2134是什么意思?

7
在我修复的某些代码中,大量使用了泛型和接口类型,我遇到了错误E2134,“Type '' 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”没有类型信息。在我看来,这是Pascal/Delphi的一个奇怪之处,完全违反了Wirth强类型的思想。它的类型弱到像C语言中的“void *”指针或Delphi中的“Pointer”类型,但它很少使用,除了像Move等标准的Pre-Object-Pascal RTL函数中。在我的观点中,在泛型中使用的接口中的无类型参数应该被允许或禁止,而不是有时允许,有时禁止。
这是1978年Pascal特性与2009年ObjectPascal特性混合的一个案例。
2个回答

17

这个错误消息意味着没有可用于给定类型的类型信息。

这是一个产生该错误消息的最小程序:

type
  {$M+}
  IThing = interface
    procedure P(const X);
  end;
  {$M-}
begin
end.
问题似乎在于IThingListOf<>或其祖先中启用了{$M+}编译选项。编译器认为您真的需要完整的接口类型信息;最初它被用于SOAP等支持来生成存根。接口RTTI不支持无类型参数(从逻辑上讲,它们无法由SOAP等进行编组),它们显示为void类型,并出现此错误消息。
解决方案是要么不使用{$M+} - 虽然可能正在使用RTTI,否则它就不会被启用 - 要么使用例如Pointer,并显式传递地址。

1

从这个代码来看很难说,特别是没有IThingContainer的定义。如果你把接口定义注释掉,那么编译器会通过吗?显然,当你尝试创建一个实现该接口的类时,它会出错,但是注释掉它可以解决这个问题吗?

如果可以,那么编译器可能在接口定义中遇到了一些问题。尝试注释掉其中的一部分以确定问题所在。如果不行,那么你就需要在其他地方寻找答案。


似乎只有在IThingContainer定义的接口方法中包含函数中未指定类型的参数时才会出现这种情况。真正奇怪的是,有时你可以在函数中定义未指定类型的参数,有时则不行。我正在查看一个大量使用未指定类型参数的代码库。将IThingContainer中的所有参数都更改为已指定类型可以解决问题,但我找不到任何关于为什么会发生这种情况的信息。 - Warren P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接