Enabling Casting

From RAD Studio
Jump to: navigation, search

Go Up to Creating a Class to Enable the Custom Variant Type


One of the most important features of the custom variant type for you to implement is typecasting. The flexibility of variants arises, in part, from their implicit typecasts.

There are two methods for you to implement that enable the custom Variant type to perform typecasts: Cast, which converts another variant type to your custom variant, and CastTo, which converts your custom Variant type to another type of Variant.

When implementing either of these methods, it is relatively easy to perform the logical conversions from the built-in variant types. You must consider, however, the possibility that the variant to or from which you are casting may be another custom Variant type. To handle this situation, you can try casting to one of the built-in Variant types as an intermediate step.

For example, the following Cast method, from the TComplexVariantType class uses the type Double as an intermediate type:

Delphi:

 procedure TComplexVariantType.Cast(var Dest: TVarData; const Source: TVarData);
 var 
 LSource, LTemp: TVarData;
 begin
   VarDataInit(LSource);
   try
     VarDataCopyNoInd(LSource, Source);
     if VarDataIsStr(LSource) then
       TComplexVarData(Dest).VComplex :=    TComplexData.Create(VarDataToStr(LSource))
     else
     begin
       VarDataInit(LTemp);
       try
         VarDataCastTo(LTemp, LSource, varDouble);
         TComplexVarData(Dest).VComplex := TComplexData.Create(LTemp.VDouble, 0);
       finally
         VarDataClear(LTemp);
       end;
     end;
     Dest.VType := VarType;
   finally
     VarDataClear(LSource);
   end;
 end;

In addition to the use of Double as an intermediate Variant type, there are a few things to note in this implementation:

  • The last step of this method sets the VType member of the returned TVarData record. This member gives the Variant type code. It is set to the VarType property of TComplexVariantType, which is the Variant type code assigned to the custom variant.
  • The custom variant's data (Dest) is typecast from TVarData to the record type that is actually used to store its data (TComplexVarData). This makes the data easier to work with.
  • The method makes a local copy of the source variant rather than working directly with its data. This prevents side effects that may affect the source data.

When casting from a complex variant to another type, the CastTo method also uses an intermediate type of Double (for any destination type other than a string).

Delphi:

 procedure TComplexVariantType.CastTo(var Dest: TVarData; const Source: TVarData; const AVarType: TVarType);
 var
 LTemp: TVarData;
 begin
   if Source.VType = VarType then
     case AVarType of
       varOleStr:
         VarDataFromOleStr(Dest, TComplexVarData(Source).VComplex.AsString);
       varString:
         VarDataFromStr(Dest, TComplexVarData(Source).VComplex.AsString);
     else
       VarDataInit(LTemp);
       try
         LTemp.VType := varDouble;
         LTemp.VDouble := TComplexVarData(LTemp).VComplex.Real;
         VarDataCastTo(Dest, LTemp, AVarType);
       finally
         VarDataClear(LTemp);
       end;
     end
   else
     RaiseCastError;
 end;

Note that the CastTo method includes a case where the source variant data does not have a type code that matches the VarType property. This case only occurs for empty (unassigned) source variants.

See Also