Wodzu
Wodzu

Reputation: 6979

E2506 Method of parameterized type declared in interface section must not use local symbol

could someone explain to me what is the reason that when creating a generic class I must move my private constans to the interface section? This is killing my design, I don't want others to see something that should be private.

unit Unit38;

interface

uses
  Generics.Collections;

type
  TSimpleClass<T> = class(TObject)
  private
    procedure DoSomethingInternal(const SomeString: string);
  public
    procedure DoSomething;
  end;

implementation

const
  MyString = 'some string'; //Why this must be public?

{ TSimpleClass<T> }

procedure TSimpleClass<T>.DoSomething;
begin
  DoSomethingInternal(MyString); //Compiler error
end;

procedure TSimpleClass<T>.DoSomethingInternal(const SomeString: string);
begin
  //-------
end;

end.

Thanks.

Upvotes: 13

Views: 2037

Answers (3)

Marjan Venema
Marjan Venema

Reputation: 19346

Same error in D2010, so the generics fixes of D2010 did not address this. It is a bug: http://qc.embarcadero.com/wc/qcmain.aspx?d=79747

Fixed in build 15.0.3863.33207. Which I think is XE

Another QC on this is: http://qc.embarcadero.com/wc/qcmain.aspx?d=78022 which involves an enum and is still open.

The documentation on the error isn't very clear by the way. See:

E2506 Method of parameterized type declared in interface section must not use local symbol '%s'

It involves a class var in a generic class which cannot be assigned a literal (!) value in the class' constructor, the fix being to parameretrize the constructor... No idea why, but I guess it has to do with a compiler limitation.

Upvotes: 6

Mikael Eriksson
Mikael Eriksson

Reputation: 138960

Not an answer but a possible workaround could be to use private const in the class declaration.

TSimpleClass<T> = class(TObject)
private
    procedure DoSomethingInternal(const SomeString: string);
    const MyString = 'some string'; //Why this must be public?
public
    procedure DoSomething;
end;

This works in Delphi 2010, XE and XE2, not in Delphi 2009.

Upvotes: 6

David Heffernan
David Heffernan

Reputation: 612963

It's a consequence of the generics implementation in Delphi. When you instantiate a class by supplying a concrete T in another unit, code for the concrete class is written into that other unit. But that other unit can no longer see your private string constant. It's rather frustrating.

My understanding of the generics implementation suggests that Mikael's workaround will solve the problem because the class const will be visible when you instantiate your concrete type in another unit.

Upvotes: 7

Related Questions