キャストを有効にする
クラスを作成してカスタム バリアント型を有効にする への移動
カスタム バリアント型の実装上最も重要な機能の 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
メンバを設定しています。このメンバはバリアント型コードを示します。これがTComplexVariantType
の VarType プロパティ(カスタム バリアントに割り当てられるバリアント型コード)に設定されます。 - カスタム バリアントのデータ(
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
プロパティと一致する型コードがソース バリアント データに含まれていないケースがあることに注意してください。これは、空の(割り当てられていない)ソース バリアントの場合にのみ発生します。