Reputation: 1438
I am trying to write a basic factory method to return a generic interfaced class.
interface
type
IGenInterface<T> = interface
function TestGet:T;
end;
TBuilder<T> = class
class function Build: IGenInterface<T>;
end;
TBuilder = class
class function Build<T>: IGenInterface<T>;
end;
implementation
type
TInterfaceImpl<T> = class(TInterfacedObject, IGenInterface<T>)
function TestGet:T;
end;
{ TBuilder }
class function TBuilder.Build<T>: IGenInterface<T>;
begin
result := TInterfaceImpl<T>.create;
end;
{ TInterfaceImpl<T> }
function TInterfaceImpl<T>.TestGet: T;
begin
end;
It looks simple enough, and I'm sure I've written similar code before, but as soon as I try to compile I get E2506: Method of parameterized type declared in interface section must not use local symbol '.TInterfaceImpl` 1'. Neither flavour of TBuilder work, both failing with the same error.
Now I'm not sure where the .
and 1
are coming from. In my 'real' code, the .
isn't there, but the ` 1 is.
I've had a look at the other two SO questions that reference this error, but I'm not using any constants or assigning variables (other than the function return) nor do I have any class vars.
Does anyone have a way to do this without having to move a lot of code into my interface?
Upvotes: 2
Views: 217
Reputation: 612954
The issue relates to an implementation detail of generics. When you come to instantiate the generic type in a different unit it needs to see the TInterfaceImpl<T>
type in that other unit. But the compiler cannot see it because it is in the implementation section of a different unit. So the compiler objects, as you have observed.
The simplest fix is to move TInterfaceImpl<T>
to be a private type declared inside one of the types declared in the interface section.
type
TBuilder = class
private
type
TInterfaceImpl<T> = class(TInterfacedObject, IGenInterface<T>)
public
function TestGet: T;
end;
public
class function Build<T>: IGenInterface<T>;
end;
Or inside the other class:
type
TBuilder<T> = class
private
type
TInterfaceImpl = class(TInterfacedObject, IGenInterface<T>)
public
function TestGet: T;
end;
public
class function Build: IGenInterface<T>;
end;
Upvotes: 6