2016-11-12 4 views
7

я создаю две единицы и поставить первый класс в одну из них:Не могу понять 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. 

И я поставил производный класс на второй блок:

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 Error] 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 Не удается получить доступ к защищенному символу TBaseOuterClass.TBaseInnerClass при линейной функции TDerOuterClass.GetInnerInstance: TBaseOuterClass.TBaseInnerClass; – tikskit

+2

Прочитайте свой комментарий, прочитайте ответ. Обратите внимание, что код в вашем комментарии отличается от кода в ответе. Используйте код в ответе. –

+0

О, право. Это работает! Благодаря! – tikskit