如何获取访问Variant类型的Delphi 6索引属性的底层原始Variant值?

3

我是一个Delphi 6类对象,包含一个由30个变量组成的数组,每个变量通过不同的索引属性公开。例如:

property responseCode: integer
        Index 7 read getIndexedProperty_integer write setIndexedProperty_integer;

我这样做是为了让使用变体数组更加容易(有助于IDE的自动完成)并提供类型安全性。它很好用,但现在我遇到了一个问题。当包装它的类被构造时,变体数组被初始化为NULL,因此我可以知道是否曾经给某个变体实例化过值。这样做的一个后果是,如果只有一些变体被实例化(给定有效值),任何尝试访问当前表示NULL变体的属性的操作都会导致Variant转换错误,因为Delphi尝试将变体转换为索引属性声明的类型。
我不想为每个索引属性声明一个“isValid”属性。我想知道是否有一种方法可以使用TypeInfo库获取基础Variant的原始值,而无需直接访问索引属性,从而触发转换异常。然后,我就可以编写如下代码(使用上面的示例属性):
isValidProperty(responseCode);

如果响应代码属性下层的变量不为空,则该函数将返回TRUE,否则返回FALSE。

我知道我可以遍历类的PPropList属性列表并通过名称访问属性,但这样我就必须使用以下代码:

isValidProperty('responseCode');

是否有一种方法可以以字符串形式传递属性名称,而不像上面的第一个isValidProperty()那样直接传递属性?


我怀疑你能否做到这一点,因为RTTI对于将变量值分配给getIndexedProperty_integer方法中的整数属性所知甚少,因此无法以这种方式访问底层变量值。我的建议是修改每个getter方法的代码,添加VarIsNull函数来检查变量值。 - RRUZ
我们正在做类似的事情,但是当 Variant 为空时,访问器会返回默认值。 - Jens Mühlenhoff
为什么使用变体可以“提供类型安全性”?从某种意义上说,它提供了相反的效果:您在此处面临的问题是不知道底层类型,只能在运行时找出。难道更好的解决方案不是拥有一个整数数组,或者如果每个30个具有不同类型,则明确具有不同属性吗? - David
@DavidM。变量不提供类型安全性,这就是访问变量的类型安全(显式声明)索引属性所提供的。变量在我应用程序需要的其他方面提供了灵活性。 - Robert Oschler
1个回答

1
所以你想要“获取底层 Variant 的原始值,而不必直接访问索引属性,从而触发转换异常”。只要您可以访问底层 Variant 本身,是的,您可以。您很可能需要更改容器类本身。
来自Delphi XE2 变体类型帮助页面

标准函数 VarType 返回变量的类型代码。 varTypeMask 常量是一个位掩码,用于从 VarType 的返回值中提取代码,例如:

VarType(V) and varTypeMask = varDouble

如果V包含一个Double或者一个Double数组,则返回True。(掩码只是隐藏了第一位,该位指示变量是否持有一个数组。)在System单元中定义的TVarData记录类型可用于类型转换变量并访问其内部表示。
您应该能够使用此处提到的方法和记录的组合来查找有关变量内部数据的任何信息,包括它是否为NULL变量以及直接访问它。
(这个系统对我来说似乎有点不安全的设计:它似乎不是一个非常类型安全的实现...请参见我上面的评论。我认为基于您期望的值的实际类型的设计可能更安全。但是,这将让您实现您的目标。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接