【问题标题】:Has Variant behavior changed in Delphi 11?Delphi 11 中的变体行为是否发生了变化?
【发布时间】:2022-01-11 19:11:03
【问题描述】:

在 Delphi 10.3 中,我编写了一些 Excel 自动化代码。我使用了变体。例程完成后,我清除并释放了 Variant...

  VarClear(arrData);
  FreeAndNil(arrData);

这编译并运行良好。我刚刚升级到 D11,即 Alexandria。此代码现在给出错误。 ... 不兼容的类型:TObject 和 Variant。

我将这部分代码改写为:

  VarClear(arrData);
  arrData.Free;

这样编译,乍一看,似乎运行良好。这是在亚历山大清除/处理变种的正确方法吗?

【问题讨论】:

  • 我没有D11,但是根据您的描述,他们将FreeAndNil(var obj)重新定义为procedure FreeAndNil(var Obj:TObject)。现在,由于Free 是 TObject 的一个方法并且与变体无关,除非他们为引入“免费”方法的变体添加了帮助器,这对我来说看起来非常错误。

标签: delphi variant


【解决方案1】:

确切地说,在 Delphi 10.4 中,FreeAndNil() 的签名确实发生了变化:

https://blog.marcocantu.com/blog/2020-may-delphi-104-rtl.html

我们更新了 FreeAndNil 过程的签名,以避免将其与接口引用和其他不受支持的数据类型一起使用。现在声明它需要对 TObject 的引用:

procedure FreeAndNil(const [ref] Obj: TObject); inline;

这意味着 FreeAndNil 的不正确使用现在会导致编译器错误。 过去,不正确的使用不会被捕获,从而导致困难的错误。请注意,虽然参数声明为 const,但引用变量确实被修改了。

首先尝试Free()Variant 是错误的。这从来没有起作用,并且应该从来没有首先出现在您的代码中。在旧定义下,FreeAndNil() 会在Variant 上调用TObject.Free(),这是错误的。在您的新代码下,arrData.Free; 将编译,但将在运行时调用方法调度来调用 Excel 对象上不存在的 Free() 方法,这将失败。

所以,完全删除Free,它不属于这里。在所有 Delphi 版本中,手动将 Variant 重置为默认状态的正确解决方案是将 Variants.NullVariants.Unassigned 分配给它,例如:

arrData := Null;
arrData := Unassigned;

【讨论】:

  • 很好的答案!
  • FreeAndNil 在(对象类型)属性中调用时(错误地)不会抱怨。这是非常错误的,Emb 已经将一个糟糕的解决方案换成了另一个糟糕的解决方案。见stackoverflow.com/questions/62479148
【解决方案2】:

这两个代码 sn-ps 都是错误的。您不会在变体上调用 Free。您在对象实例上调用 Free。只需删除该行。

【讨论】:

  • 在你告诉我以前的代码可以工作之前,它没有。它一直都是错误的,而你却以某种方式侥幸逃脱了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-20
  • 2011-12-28
  • 1970-01-01
  • 2020-12-03
  • 2017-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多