@@ -657,6 +657,8 @@ TValueHelper = record helper for TValue
657657 // / </summary>
658658 function IsString : Boolean;
659659
660+ function IsType (ATypeInfo: PTypeInfo): Boolean; overload;
661+
660662 // / <summary>
661663 // / Checks whether the stored value is a <c>Variant</c>.
662664 // / </summary>
@@ -669,6 +671,8 @@ TValueHelper = record helper for TValue
669671
670672 function TryAsType (typeInfo: PTypeInfo; out target): Boolean; overload;
671673
674+ function TryCast (ATypeInfo: PTypeInfo; out AResult: TValue): Boolean;
675+
672676 // / <summary>
673677 // / Tries to convert the stored value. Returns false when the conversion
674678 // / is not possible.
@@ -5740,6 +5744,13 @@ function TValueHelper.IsString: Boolean;
57405744 Result := Kind in StringKinds;
57415745end ;
57425746
5747+ function TValueHelper.IsType (ATypeInfo: PTypeInfo): Boolean;
5748+ var
5749+ unused: TValue;
5750+ begin
5751+ Result := TryCast(ATypeInfo, unused);
5752+ end ;
5753+
57435754function TValueHelper.IsVariant : Boolean;
57445755begin
57455756 Result := TypeInfo = System.TypeInfo(Variant);
@@ -6034,6 +6045,32 @@ function TValueHelper.TryAsType(typeInfo: PTypeInfo; out target): Boolean;
60346045 value .ExtractRawData(@target);
60356046end ;
60366047
6048+ function TValueHelper.TryCast (ATypeInfo: PTypeInfo;
6049+ out AResult: TValue): Boolean;
6050+ begin
6051+ // fix wrong logic in RTL:
6052+ // typecasting a TValue that contains a reference type that is nil succeeds
6053+ // in all cases which clearly is against the otherwise strict type cast rules
6054+
6055+ if not ((TValueData(Self).FTypeInfo = nil ) or (TValueData(Self).FValueData = nil )) then
6056+ if IsEmpty and Assigned(ATypeInfo) and (Kind <> ATypeInfo.Kind) then
6057+ case Kind of
6058+ tkClass:
6059+ if not (ATypeInfo.Kind in [tkVariant, tkInterface, tkPointer]) then
6060+ Exit(False);
6061+ tkInterface:
6062+ if not (ATypeInfo.Kind in [tkVariant, tkPointer]) then
6063+ Exit(False);
6064+ tkDynArray:
6065+ if TValueData(Self).FTypeInfo <> ATypeInfo then
6066+ Exit(False);
6067+ tkPointer:;
6068+ else
6069+ Exit(False);
6070+ end ;
6071+ Result := TValueHack(Self).TryCast(ATypeInfo, AResult);
6072+ end ;
6073+
60376074
60386075{ $REGION 'Conversion functions'}
60396076type
0 commit comments