I create two units and put a first class into one of them:
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.
And I put a derived class into a second unit:
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.
When I'm trying to compile I get
[dcc32 Error] UDerClass.pas(22): E2362 Cannot access protected symbol TBaseOuterClass.TBaseInnerClass
at the line function TDerOuterClass.GetInnerInstance: TBaseOuterClass.TBaseInnerClass;
I can't understand why TBaseOuterClass.TBaseInnerClass (as inner protected class) isn't accessible from TDerOuterClass (which is derived for TBaseOuterClass). What in this case are protected types actually for?
I haven't found any explanation for this at Nested Type Declarations topic. So are there any reasons for this behaviour?
It's also relevant to simple protected types like
protected type
TSimpleType = Integer;
I can't write a function in TDerOuterClass
protected
function GetValue: TSimpleType;
since I'll get a message
[dcc32 Error] UDerClass.pas(16): E2003 Undeclared identifier: 'TSimpleType'
It looks like a bug. I would suggest to post it to the quality portal.
For now you could declare type alias to cheat the compiler (tested in 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With