2015-12-02 4 views
2

Я пытаюсь написать базовый заводский метод для возврата общего сопряженного класса.Метод параметризованного типа не должен использовать ошибку локального символа при создании фабрики общих интерфейсов

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; 

Это выглядит достаточно просто, и я уверен, что я написал подобный код и раньше, но как только я пытаюсь скомпилировать я получаю E2506: Метод параметризированного типа, объявленный в интерфейсе раздела не должен использовать локальный символ '.TInfacefaceImpl` 1'. Ни тот вкус, ни TBuilder не работают, оба с той же ошибкой.

Теперь я не уверен, откуда берутся . и 1. В моем «реальном» коде . не существует, но `1 есть.

Я рассмотрел два других вопроса SO, которые ссылаются на эту ошибку, но я не использую никаких констант или не присваиваю переменные (кроме функции return), и у меня нет классов классов.

У кого-нибудь есть способ сделать это, не перекладывая много кода в мой интерфейс?

ответ

6

Эта проблема относится к деталям реализации дженериков. Когда вы приходите для создания экземпляра родового типа в другом блоке, он должен видеть тип TInterfaceImpl<T> в этом другом устройстве. Но компилятор не видит этого, потому что он находится в разделе реализации другого устройства. Таким образом, объекты компилятора, как вы заметили.

Простейшим решением является перемещение TInterfaceImpl<T> как частного типа, объявленного внутри одного из типов, объявленных в разделе интерфейса.

type 
    TBuilder = class 
    private 
    type 
     TInterfaceImpl<T> = class(TInterfacedObject, IGenInterface<T>) 
     public 
     function TestGet: T; 
     end; 
    public 
    class function Build<T>: IGenInterface<T>; 
    end; 

Или внутри другого класса:

type 
    TBuilder<T> = class 
    private 
    type 
     TInterfaceImpl = class(TInterfacedObject, IGenInterface<T>) 
     public 
     function TestGet: T; 
     end; 
    public 
    class function Build: IGenInterface<T>; 
    end; 
+0

Очень странно выглядящий структура, что ничего подобного не видел. Также необходимо, чтобы функции реализации были 'TBuilder.TInterfaceImpl .TestGet', который, к счастью, автозаполнение знает, как обращаться. –

 Смежные вопросы

  • Нет связанных вопросов^_^