我有一个OleVariant
或Variant
值,例如,用 读取IXMLNode.GetAttributeNS
,使其成为“字符串”(varOleStr
或varString
),我想用 写该值,例如,TRTTIField.SetValue
需要与 的TValue
赋值兼容TRTTIField.FieldType: TRTTIType
。
对于基本类型(以及TVarType
和),我不是将TRTTIType.TypeKind: TTypeKind
每个单独的案例:case VarType(Value) and varTypeMask of varXXXX: ... end
OleVariant
Variant
TValue
TRTTIType
在 Variant 和 RTTI 世界之间转换值的方法是什么?
此外,Spring4D 库是项目的一部分,以防万一。
更新:
从技术上讲,我正在寻找Convert
以下代码(在 Variant 世界中转换):
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;
但是,我发现VariantChangeTypeEx
我不知道如何关联Left.FieldType
它以使后续代码正常工作。-- 我也不介意在 RTTI 世界中进行转换,而是从Temp := TValue.FromVariant(Right)
( tkUString
) 开始,然后以某种方式达到分配兼容性;所以Temp.Kind
会变成tkEnumeration
/Boolean, tkFloat
,... 由Left.FieldType.TypeKind
.
如何使用 RTTI 分配变体?或者,如何将 Variant 转换为 TValue 然后分配它?
注意:如果字段类型和值类型在性质上不同,RTTIField.SetValue
则会失败EInvalidCast
,因为 RTTI 不会尝试更改值的性质。我在这里的困难是达到分配兼容性。
更新:给定答案,以下代码概述了我的解决方案:
procedure (const Value: Pointer; const RTTIField: TRTTIField; const XMLNode: IXMLNode);
var
Temp1: OLEVariant;
Temp2: TValue;
begin
Assert(XMLNode.HasAttribute(Ref, Namespace));
Temp1 := XMLNode.GetAttributeNS(Ref, Namespace);
Temp2 := TValue.FromVariant(Temp1);
Temp2 := Temp2.Convert(RTTIField.FieldType.Handle{, FormatSettings}); // in Spring.TValueHelper
RTTIField.SetValue(Value, Temp2);
end;