Если абстрагироваться от типа данных, окажется, что логика очень многих алгоритмов абсолютно одинакова. Например, алгоритм быстрой сортировки идентичен как для массива целых, так и для массива вещественных чисел. В подобных ситуациях благодаря созданию обобщенной функции (функции с параметром обобщенного типа) мы сможем определить смысл алгоритма, не отвлекаясь на обслуживаемый тип данных. Поэтому обобщенный тип данных может оказаться весьма полезным при разработке шаблонов процедурных типов данных, способных воспринимать параметры любых типов.
По аналогии с объявлением обычной процедуры или функции, при создании шаблона процедуры или функции сначала указывают ключевое слово type, а затем имя типа. Сразу за именем следует синтаксический элемент, характерный для обобщений — пара угловых скобок <... > с названием обобщенного типа данных.
type тип_функции <имя_обобщенного_типа [,...]> =
function ( [параметр_обобщенного_типа [,...]]) : имя_обобщенного_типа; type тип_процедуры <шш_обобщенного_типа [,...]> =
procedure ([параметр_обобщенного_типа [,...]]
Листинг 3.2 демонстрирует порядок создания шаблона функции. В примере объявлена функция класса GetMaxValue () с двумя параметрами, тип которых не определен. Задачей функции является сравнение двух значений и возврат наибольшего из них.
uses System.SysUtils,System.Generics.Defaults;
type TGetMax = class
classfunction GetMaxValue<T>(X,Y: T):T;
end;
class function TGetMax.GetMaxValue<T>(X, Y: T): T;
var Comparer: IComparer<T>;
begin
{к сожалению, нельзя написать такой код: if X>Y thenResult:=X else Result:=Y; ведь мы не знаем тип данных сравниваемых параметров}
Comparer:=TComparer<T>.Default;
if Comparer.Compare(X,Y)>0 then Result:=X
else Result:=Y;
end;
var A:integer;
B:extended;
Ciansichar;
begin
A:=TGetMax.GetMaxValue<integer>(10,20);//сравниваем целые числа WriteLn(A);
B:=TGetMax.GetMaxValue<extended>(1/3,2/3);//вещественные числа WriteLn(В);
C:=TGetMax.GetMaxValUe<ansichar>(*Af,fBf);//сравниваемсимволы WriteLn(С); .
ReadLn;
end.