Il n'existe aucun moyen de spécifier des contraintes sur les génériques de sorte que vous pouvez exiger que les types soient des nombres, donc vous ne pouvez pas utiliser les opérateurs numériques sur les valeurs de votre liste. Craig Stuntz a écrit a series of posts décrivant comment construire une bibliothèque statistique générique, et il a rencontré le même problème. Il l'a résolu en fournissant des arguments supplémentaires à ses fonctions afin que l'appelant puisse fournir des implémentations pour les opérations numériques spécifiques au type - le modèle modèle de méthode. Voilà comment il a déclaré l'opération Average
:
type
TBinaryOp<T> = reference to function(ALeft, ARight: T): T
TStatistics<T> = class
public
class function Average(const AData: TEnumerable<T>;
AAdder, ADivider: TBinaryOp<T>;
AMapper: TFunc<integer, T>): T; overload;
Les appelants de cette fonction doivent fournir leur propre code pour ajouter, en divisant et « cartographie » le type générique. (Cartographie est couvert dans un poste plus tard et n'a pas d'importance ici.) Vous pouvez écrire votre fonction Invert
comme ceci:
type
TUnaryOp<T> = reference to function(Arg: T): T;
TKList<T> = class
procedure Invert(ANegater: TUnaryOp<T>);
procedure TKList<T>.Invert;
var
i: Integer;
begin
for i := 0 to Pred(Count) do
Values[i] := ANegater(Values[i]);
end;
Pour le rendre plus commode d'appeler les méthodes sans avoir à fournir des arguments supplémentaires tous les Stuntz a montré comment déclarer un descendant spécifique au type qui fournit les bons arguments. Vous pouvez le faire comme ceci:
type
TIntKList = class(TKList<Integer>)
private
class function Negate(Arg: Integer): Integer;
public
procedure Invert;
end;
procedure TIntKList.Invert;
begin
inherited Invert(Negate);
end;
Vous pouvez fournir des types de type spécifique descendants pour les numériques communs, et si les consommateurs de classe ont besoin d'utiliser d'autres types de numéros semblables, ils peuvent fournir leurs propres implémentations pour la opérations numériques de base sans avoir à ré-implémenter votre classe de liste entière.
Qu'est-ce que cela signifie pour « inverser » les valeurs? S'il vous plaît être plus précis sur les problèmes que vous rencontrez la mise en œuvre de cette méthode. –
Vous voulez dire inverser l'ordre des articles? Vous pouvez le faire en créant une deuxième liste, en revenant en arrière sur la liste d'origine à la fin et en ajoutant les éléments à la nouvelle liste, puis en remplaçant l'original par la nouvelle liste. –
Il a parlé de nombres entiers et de doubles, donc je suppose: pour I: = 0 à compter - 1 faire Valeurs [I]: = -Valeurs [I]; –