我有一个OleVariant
或Variant
值,例如,它是用IXMLNode.GetAttributeNS
读取的,使其成为“字符串”(varOleStr
或{{1} }),我想用varString
来写该值,要求TRTTIField.SetValue
的分配与TValue
兼容。
对于基本类型(沿TRTTIField.FieldType: TRTTIType
和TVarType
),而不是将每种情况都设为单独的情况:TRTTIType.TypeKind: TTypeKind
,我在寻找一种从{{1}转换的通用方法}或case VarType(Value) and varTypeMask of varXXXX: ... end
到OleVariant
,然后与特定的Variant
分配兼容。
在Variant和RTTI世界之间转换值的方法是什么?
此外,如果有帮助,Spring4D库是项目的一部分。
更新:
从技术上讲,我正在以下代码中寻找TValue
(在Variant世界中进行转换):
TRTTIType
我找到了VariantChangeTypeEx
,但是,我不知道如何将Convert
与它联系起来以使后续代码正常工作。 -我也不介意在RTTI世界中进行转换,而是以var
Left: TRTTIField;
Right: OleVariant;
Temp: TValue;
Instance: Pointer;
begin
{ Examples: varOleStr --> varXXXX --> assignment-compatible TValue }
Right := 'False'; // varOleStr, as read with IXMLNode.GetAttributeNS
Right := Convert(Right, Left.FieldType); // making it possibly varBoolean
Temp := TValue.FromVariant(Right); // tkEnumeration, like Left.FieldType.TypeKind
Right := '2'; // varOleStr, as read with IXMLNode.GetAttributeNS
Right := Convert(Right, Left.FieldType); // making it possibly varInteger
Temp := TValue.FromVariant(Right); // tkInteger, like Left.FieldType.TypeKind
Right := '3.1415'; // varOleStr, as read with IXMLNode.GetAttributeNS
Right := Convert(Right, Left.FieldType); // making it possibly varDoiuble
Temp := TValue.FromVariant(Right); // tkFloat, like Left.FieldType.TypeKind
Right := 'Hello!'; // varOleStr, as read with IXMLNode.GetAttributeNS
Right := Convert(Right, Left.FieldType); // making it possibly varOleStr
Temp := TValue.FromVariant(Right); // tkUString, like Left.FieldType.TypeKind
{ ... and an assignment: }
Left.SetValue(Instance, Temp);
end;
(Left.FieldType
)开始,然后以某种方式达到分配兼容性;因此Temp := TValue.FromVariant(Right)
会变成tkUString
给定的Temp.Kind
/ Boolean,tkEnumeration
...。
如何使用RTTI分配变体?或者,如何将Variant转换为TValue,然后对其进行分配?
注意:如果字段类型和值类型的性质不同,RTTIField.SetValue
将失败,并以tkFloat
结束,因为RTTI不会尝试更改值的性质。我在这里的困难是要达到作业兼容性。
更新:给出答案后,以下代码概述了我的解决方案:
Left.FieldType.TypeKind
答案 0 :(得分:3)
TValue中的内置类型强制转换在这里无济于事,因为它们只允许那些显式兼容(即可分配)的类型。从技术上讲,如果您将Variant存储在TValue中而没有“拆包”,这就是FromVariant
内部所做的事情,则它应该能够将Variant强制转换为通常可以强制转换/转换为的任何变量。但是,将变量“ True”或“ False”强制转换为布尔值至少有一个问题(请参见https://quality.embarcadero.com/browse/RSP-20160)
但是,由于您已经在使用Spring4D,因此可以使用其改进的TValue类型转换功能。
只需使用Convert
中TValueHelper
中的Spring.pas
方法。
您可以在其中传递PTypeInfo(在代码中为Left.FieldType.Handle
)和可选的TFormatSettings
-默认情况下,它将使用当前语言环境。
答案 1 :(得分:2)
在Variant和RTTI世界之间转换值的方法是什么?
在System.RTTI.TValue中使用内置的类函数转换:
myTValue := TValue.FromVariant(myVariant);
从Variant值构建新的TValue记录。
FromVariant 是一种静态方法,可用于构建具有存储的Variant值的TValue记录。 Value参数包含将存储在内置TValue记录内的Variant。