PAYATHON 2026

Chilkat 11.3 ActiveX 的 ObjectAt(-1) 为何返回对象?

数据小陈

调用 ObjectAt 前,应先检查索引是否满足 0 <= lindex < jsonArray.Size,再检查返回对象。返回值不是 Nothing,也不能据此认定取得了目标对象。

现有现象不足以确认 Chilkat 11.3 存在缺陷,也无法确定返回的是哪个对象。可以先通过边界检查恢复业务判断,再单独验证版本差异。

为什么原来的判断不够

原有代码把 ObjectAt(lindex) 返回非空值作为成功的依据。当 lindex = -1 时,如果组件仍返回对象,后续逻辑就会继续处理这个对象,即使该索引原本表示没有找到结果。

Chilkat 当前的 ActiveX 文档说明,数组索引范围是 0 到 Size - 1。ObjectAt 用于取得指定位置的 JSON object,失败时返回 Nothing。文档允许部分 Add*At 插入方法用 -1 表示追加,但这不能说明 ObjectAt(-1) 也有同样的读取约定。Chilkat JsonArray ActiveX API 文档

这些说明支持在读取前检查边界,但不能证明 11.0 与 11.3 的历史实现完全一致。题述的升级差异仍需复现确认。

另外,示例中的 if jsonObject is Not Nothing Then 应改为 VB6 的判空写法:

If Not (jsonObject Is Nothing) Then
    ' 处理对象
End If

语法修正和返回值异常需要分别处理。

在调用前检查索引和类型

下面的代码假设 jsonArray 已初始化,lindex 是准备读取的索引,且 jsonObject 已声明为对象变量:

' 先清空本次结果,避免跳过读取时继续使用上一次的对象。
Set jsonObject = Nothing

If lindex >= 0 And lindex < jsonArray.Size Then
    ' TypeAt 返回 3 表示当前位置是 JSON object。
    If jsonArray.TypeAt(lindex) = 3 Then
        Set jsonObject = jsonArray.ObjectAt(lindex)
    End If
End If

If Not (jsonObject Is Nothing) Then
    ' 在这里处理取得的 JSON object。
Else
    ' 索引无效、元素不是 object,或读取失败。
End If

如果数组可能混合包含字符串、数字、数组或 null,可以用 TypeAt 检查元素类型。返回值 3 表示当前位置是 object。Chilkat TypeAt 文档

清空变量是为了避免本次未调用 ObjectAt 时沿用旧引用,并不说明原问题由旧引用造成。索引检查才能阻止调用 ObjectAt(-1)。

如果业务用 -1 表示“查找失败”,应在这个结果进入读取流程前处理。如果要读取最后一个元素,应先确认 Size > 0,再使用 Size - 1。

如何确认版本差异

准备一个最小数组,例如:

[{"id":"first"},{"id":"last"}]

在两个版本中使用相同数据和调用顺序,分别检查:

  • 合法索引 0、1。
  • 越界索引 -1、2。
  • 新建数组后立即调用 ObjectAt(-1)。
  • 先读取索引 0 或 1,再调用 ObjectAt(-1)。
  • 空数组上的 ObjectAt(-1)。

记录实际加载的组件版本、索引、数组长度、返回值是否为 Nothing,以及非空返回对象中的 id。这些信息可以帮助区分返回对象是否与最后一个元素或前一次读取有关。

如果项目使用了 On Error Resume Next,诊断时还应检查调用后是否发生运行时错误,避免忽略错误后误判返回状态。确认可以复现后,将最小示例和准确版本信息提交给 Chilkat 支持,以进一步判断是实现缺陷还是行为变更。

使用时要注意什么

在原因明确前,不要对无效索引返回的对象执行更新或删除。官方说明,ObjectAt 返回的是原 JSON 文档中对象的引用,通过它修改数据会影响原文档。Chilkat ObjectAt 文档

边界检查可以作为调用端的稳定保护,但它不代表底层版本问题已经修复,也不代表某个更新版本一定解决了问题。

备注:内容仅供参考。