キャストを有効にする

提供: RAD Studio
移動先: 案内検索

クラスを作成してカスタム バリアント型を有効にする への移動


カスタム バリアント型の実装上最も重要な機能の 1 つは型キャストです。 バリアントの柔軟性は、一つには、暗黙の型キャストに起因します。

カスタム バリアント型の型キャストを可能にする実装対象のメソッドが 2 つあります。それは、Cast(別のバリアント型をカスタム バリアント型に変換)と CastTo(カスタム バリアント型を別のバリアント型に変換)です。

これらのメソッドのいずれかを実装するときは、組み込みのバリアント型から論理変換を実行すると比較的簡単です。ただし、キャスト先またはキャスト元のバリアントが別のカスタム バリアント型の可能性があることを考慮する必要があります。このような状況に対処するには、中間ステップとして、組み込みバリアント型の 1 つにキャストしてみるという方法もあります。

たとえば、次の例では、TComplexVariantType クラスの Cast メソッドで Double 型を中間の型として使用しています。

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;

上記の実装例には、Double 型を中間のバリアント型として使用している点のほかに、注目すべき点が次のようにいくつかあります。

  • このメソッドの最後のステップで、返された TVarData レコードの VType メンバを設定しています。このメンバはバリアント型コードを示します。これが TComplexVariantTypeVarType プロパティ(カスタム バリアントに割り当てられるバリアント型コード)に設定されます。
  • カスタム バリアントのデータ(Dest)が、TVarData から、データの格納に実際に使用されるレコード型(TComplexVarData)に型キャストされています。これにより、データが扱いやすくなります。
  • このメソッドでは、ソース バリアントのデータを直接操作するのでなく、ソース バリアントのローカル コピーを作成しています。これにより、ソース データに副作用の影響が出るのを回避しています。

次の CastTo メソッドの実装例でも、複素数バリアントから別の型にキャストするときに、(文字列以外の任意の変換先型の場合に)Double 型を中間の型として使用しています。

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;

CastTo メソッドの場合は、VarType プロパティと一致する型コードがソース バリアント データに含まれていないケースがあることに注意してください。これは、空の(割り当てられていない)ソース バリアントの場合にのみ発生します。

関連項目