Support des propriétés et des méthodes dans les variants personnalisés
Remonter à Définition de variants personnalisés - Index
Certains variants ont des propriétés et des méthodes. Par exemple, quand la valeur d'un variant est une interface, vous pouvez utiliser le variant pour lire ou écrire les valeurs des propriétés de cette interface et appeler ses méthodes. Même si votre type variant personnalisé ne représente pas une interface, vous pouvez lui donner des propriétés et des méthodes qu'une application pourra utiliser.
Utilisation de TInvokeableVariantType
Pour fournir le support des propriétés et méthodes, la classe que vous créez pour activer le nouveau type variant personnalisé doit descendre de System.Variants.TInvokeableVariantType et non directement de TCustomVariantType.
TInvokeableVariantType définit quatre méthodes :
que vous pouvez implémenter pour supporter les propriétés et les méthodes dans votre type variant personnalisé.
Par exemple, l'unité System.VarConv utilise TInvokeableVariantType comme classe de base pour TConvertVariantType de sorte que les variants personnalisés résultant puissent supporter les propriétés. L'exemple suivant présente l'accès en lecture pour ces propriétés :
Delphi :
function TConvertVariantType.GetProperty(var Dest: TVarData;
const V: TVarData; const Name: String): Boolean;
var
LType: TConvType;
begin
// supports...
// 'Value'
// 'Type'
// 'TypeName'
// 'Family'
// 'FamilyName'
// 'As[Type]'
Result := True;
if Name = 'VALUE' then
Variant(Dest) := TConvertVarData(V).VValue
else if Name = 'TYPE' then
Variant(Dest) := TConvertVarData(V).VConvType
else if Name = 'TYPENAME' then
Variant(Dest) := ConvTypeToDescription(TConvertVarData(V).VConvType)
else if Name = 'FAMILY' then
Variant(Dest) := ConvTypeToFamily(TConvertVarData(V).VConvType)
else if Name = 'FAMILYNAME' then
Variant(Dest) := ConvFamilyToDescription(ConvTypeToFamily(TConvertVarData(V).VConvType))
else if System.Copy(Name, 1, 2) = 'AS' then
begin
if DescriptionToConvType(ConvTypeToFamily(TConvertVarData(V).VConvType), System.Copy(Name, 3, MaxInt), LType) then
VarConvertCreateInto(Variant(Dest), Convert(TConvertVarData(V).VValue, TConvertVarData(V).VConvType, LType), LType)
else
Result := False;
end
else
Result := False;
end;
La méthode GetProperty vérifie le paramètre Name
pour déterminer quelle propriété est demandée. Elle récupère ensuite l'information de l'enregistrement TVarData du Variant (V
), et la renvoie sous forme du Variant (Dest
). Remarquez que cette méthode supporte les propriétés dont les noms sont générés de façon dynamique à l'exécution (As[Type]), en se basant sur la valeur en cours du variant personnalisé.
De même, les méthodes SetProperty, DoFunction et DoProcedure sont suffisamment génériques pour que vous puissiez générer de façon dynamique les noms des méthodes ou répondre aux divers nombres et types de paramètres.
Utilisation de TPublishableVariantType
Si le type variant personnalisé stocke ses données en utilisant l'instance d'un objet, alors il existe un moyen plus simple d'implémenter des propriétés, si ce sont aussi les propriétés de l'objet qui représente les données du variant. Si vous utilisez System.TypInfo.TPublishableVariantType comme classe de base pour votre type variant personnalisé, alors il vous suffit d'implémenter la méthode GetInstance et toutes les propriétés publiées de l'objet qui représente les données du variant seront implémentées automatiquement pour les variants personnalisés.
Par exemple, comme on l'a vu dans Stockage des données d'un type Variant personnalisé, TComplexVariantType stocke les données d'un variant à valeur complexe en utilisant une instance de TComplexData. TComplexData possède un certain nombre de propriétés publiées (Real, Imaginary, Radius, Theta et FixedTheta), qui fournissent des informations sur la valeur complexe. TComplexVariantType descend de TPublishableVariantType et implémente la méthode GetInstance
pour renvoyer l'objet TComplexData (de TypInfo.pas) qui est stocké dans l'enregistrement TVarData du variant à valeur complexe.
Delphi :
function TComplexVariantType.GetInstance(const V: TVarData): TObject;
begin
Result := TComplexVarData(V).VComplex;
end;
TPublishableVariantType fait le reste. Il redéfinit les méthodes GetProperty
et SetProperty
pour qu'elles utilisent les informations de type à l'exécution (RTTI) de l'objet TComplexData pour lire et écrire les valeurs de propriétés.
- Remarque : Pour que TPublishableVariantType fonctionne, l'objet qui contient les données du variant personnalisé doit être compilé avec RTTI. Cela signifie qu'il doit être compilé en utilisant la directive {$M+} ou descendre de TPersistent.