无法理解Delphi XE6保护类型

tik*_*kit 7 delphi delphi-xe6

我创建了两个单元并将第一个类放入其中一个:

  unit UBaseClass;

  interface

  type
    TBaseOuterClass = class
    protected type

      TBaseInnerClass = class
      public
      end;

    protected
      function GetInnerInstance: TBaseOuterClass.TBaseInnerClass; virtual;
    end;

  implementation

  { TBaseOuterClass }

  function TBaseOuterClass.GetInnerInstance: TBaseOuterClass.TBaseInnerClass;
  begin
  // doesn't matter
  end;

  end.
Run Code Online (Sandbox Code Playgroud)

我将派生类放入第二个单元:

unit UDerClass;

interface

uses
  UBaseClass;

type
  TDerOuterClass = class(TBaseOuterClass)
  protected type

    TDerInnerClass = class(TBaseInnerClass)

    end;

  protected
    function GetInnerInstance: TBaseOuterClass.TBaseInnerClass; override;
  end;

implementation

{ TDerOuterClass }

function TDerOuterClass.GetInnerInstance: TBaseOuterClass.TBaseInnerClass;
begin

end;

end.
Run Code Online (Sandbox Code Playgroud)

当我正在尝试编译时,我得到了

[dcc32错误] UDerClass.pas(22):E2362无法访问受保护的符号TBaseOuterClass.TBaseInnerClass

在行函数TDerOuterClass.GetInnerInstance:TBaseOuterClass.TBaseInnerClass;

我无法理解为什么TBaseOuterClass.TBaseInnerClass(作为内部受保护类)无法从TDerOuterClass(为TBaseOuterClass派生)访问.在这种情况下,实际上受保护类型是什么?

我在嵌套类型声明主题中没有找到任何解释.那么这种行为有什么理由吗?

它也与简单的受保护类型相关

protected type    
  TSimpleType = Integer;
Run Code Online (Sandbox Code Playgroud)

我无法在TDerOuterClass中编写函数

protected    
  function GetValue: TSimpleType;
Run Code Online (Sandbox Code Playgroud)

因为我会收到一条消息

[dcc32错误] UDerClass.pas(16):E2003未声明的标识符:'TSimpleType'

Max*_*ich 12

它看起来像一个bug.我建议将其发布到质量门户网站.

现在你可以声明类型别名来欺骗编译器(在XE7中测试).

unit UDerClass;

interface

uses
  UBaseClass;

type
  TDerOuterClass = class(TBaseOuterClass)
  protected type
    TBaseInnerClass = TBaseOuterClass.TBaseInnerClass; // <= type alias to avoid compiler error

    TDerInnerClass = class(TBaseInnerClass)

    end;

  protected
    function GetInnerInstance: TBaseInnerClass; override;
  end;

implementation

{ TDerOuterClass }

function TDerOuterClass.GetInnerInstance: TBaseInnerClass;
begin
  Result := TDerInnerClass.Create;
end;

end.
Run Code Online (Sandbox Code Playgroud)

  • 阅读您的评论,阅读答案.请注意,评论中的代码与答案中的代码不同.使用答案中的代码. (2认同)
  • @DavidHeffernan我添加了[one](https://quality.embarcadero.com/browse/RSP-16305) (2认同)