E2506 метод параметризованного типа, объявленный в разделе интерфейса, не должен использовать локальный символ

может кто-нибудь объяснит мне в чем причина что при создании универсального класса я должен переместить мои личные константы в раздел интерфейса? Это убивает мой дизайн, я не хочу, чтобы другие видели то, что должно быть частным.

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.

спасибо.

3 ответов


та же ошибка в D2010, поэтому исправления дженериков D2010 не касались этого. Это ошибка:http://qc.embarcadero.com/wc/qcmain.aspx?d=79747

исправлено в сборке 15.0.3863.33207. Который, я думаю, XE

другой QC на этом:http://qc.embarcadero.com/wc/qcmain.aspx?d=78022 который включает перечисление и все еще открыт.

документация по ошибке, кстати, не очень ясна. См.:

E2506 Метод параметризованного типа, объявленный в разделе интерфейса, не должен использовать локальный символ "%s"

Он включает в себя класс var в общем классе, который не может быть назначен литералом (!) значение в конструкторе класса, исправление заключается в parameretrize конструктора... Не знаю почему, но я думаю, что это связано с ограничением компилятора.


Это следствие реализации дженериков в Delphi. Когда вы создаете экземпляр класса, предоставляя конкретный T в другом блоке, код для конкретного класса записывается в этот другой блок. Но эта другая единица больше не может видеть вашу личную строковую константу. Это довольно неприятно.

мое понимание реализации дженериков предполагает, что обходной путь Микаэля решит проблему, потому что класс const будет виден при создании экземпляра вашего конкретного типа в другом подразделении.


Не ответ, но возможным обходным путем может быть использование private const в объявлении класса.

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

это работает в Delphi 2010, XE и XE2, а не в Delphi 2009.