2016-11-12 35 views
7

我创建了两个单位,并把第一类为其中之一:不能理解德尔福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. 

我把一个派生类到第二单元:

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. 

当我试图编译我得到

[dcc32错误] UDerClass.pas(22):E2362无法访问受保护的象征 TBaseOuterClass.TBaseIn nerClass

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

我不明白为什么TBaseOuterClass.TBaseInnerClass(作为内部保护类)不能从TDerOuterClass(它是为TBaseOuterClass派生)访问。在这种情况下,保护类型实际上是什么?

我还没有在Nested Type Declarations topic找到任何解释。那么这种行为有什么原因吗?

这也涉及到简单的保护类型,如

protected type  
    TSimpleType = Integer; 

我不能在TDerOuterClass

protected  
    function GetValue: TSimpleType; 

写一个函数,因为我会得到一个消息

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

+1

你的例子和分析非常清楚。这似乎是一个缺陷。向质量门户提交错误报告。 –

+2

在10.2东京地区修正:https://quality.embarcadero.com/browse/RSP-16305 –

回答

12

它看起来像一个错误。我建议将它发布到quality portal

现在,您可以声明类型别名来欺骗编译器(在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. 
+0

不可以。它在Delphi XE6中不起作用。说[dcc32错误] UDerClass.pas(45):E2362无法在行函数TDerOuterClass.GetInnerInstance:TBaseOuterClass.TBaseInnerClass;上访问受保护的符号TBaseOuterClass.TBaseInnerClass; – tikskit

+2

阅读您的评论,阅读答案。请注意,评论中的代码与答案中的代码不同。使用答案中的代码。 –

+0

哦,对。它的作品呢!谢谢! – tikskit