2013-08-26 3 views
6

Почему в Delphi (XE) возникает ошибка?Вызвать метод на общий тип?

unit UTest; 

interface 


type 

TTest = class 
    public 
    procedure Foo<T>(A: T); 
end; 

implementation 

{ TTest } 

procedure TTest.Foo<T>(A: T); 
begin 
    A.Add('hej'); 
end; 

end. 

Я думал, что родовые типы в Delphi просто вставляется в родовой функции, так что ошибка будет только при использовании с типом, которые не имеют метод Add (строка).

ответ

8

Ваш код создает ошибку компиляции, потому что компилятор не знает, что T имеет метод с именем Add, который получает один строковый параметр.

Я думал, что общие типы в Delphi просто вставляются в общую функцию, поэтому она будет иметь ошибку только при использовании с типом, который не имеет метода Add (string).

Если вы используете шаблоны Smalltalk или C++, ваше предположение было бы точным. Однако дженерики не совпадают с шаблонами. Для дженериков вам нужно применить ограничение к параметру type. Ограничение должно сообщить компилятору, какие свойства должны иметь свойства T.

Например, вы можете ограничить T производным от класса, который имеет подходящий метод Add. Или вы можете ограничить T, чтобы реализовать интерфейс с подходящим методом Add.

документации ссылка на Delphi общих ограничений: http://docwiki.embarcadero.com/RADStudio/en/Constraints_in_Generics

Обобщенные ограничения, которые могут быть применены весьма ограничены, что является чем-то вроде стыда. Например, я бы хотел, чтобы удержать тип, чтобы иметь определенные математические операторы. Например, я хотел бы иметь возможность ограничить тип операторов + и -. Однако есть плюсы и минусы как для генериков, так и для шаблонов, и поэтому я согласен с тем, что эти ограничения являются результатом обоснованного дизайнерского решения разработчиками языка Delphi.

+0

Причина, по которой я хочу сделать это, состоит в том, что у меня есть два класса, которые не разделяют базовый класс (или интерфейс), но некоторые подписи метода точно такие же. Думаю, это невозможно с ограниченными ограничениями? – monoceres

+1

Это правильно. Если бы это были шаблоны, все было бы хорошо. Но вам просто не повезло с дженериками. Вы столкнулись с той же проблемой, которая мешает мне писать хорошие математические алгоритмы, которые могут работать как с скалярными, так и с комплексными значениями. –

+1

Это очень плохо :(Думаю, мне придется вернуться к RTTI и if-statements (blersh). – monoceres