使用ToString作为变量

以下代码产生一个EVariantInvalidOpError异常:

var
  i : Variant;
begin
  i := 10;
  ShowMessage(i.ToString());
end;

使用ToString作为变量

以下所有方法都可以正常工作,但我不明白为什么ToString函数会引发Variant类型变量的异常:

var
  i : Variant;
begin
  i := 10;
  ShowMessage(VarToStr(i));
end;

var
  i : Integer;
begin
  i := 10;
  ShowMessage(i.ToString());
end;
iCMS 回答:使用ToString作为变量

变量使您可以在其中存储各种类型的值,而在编译时该类型可能是未知的。您可以将整数值写入Variant的单个变量中,然后再用字符串值覆盖它。连同值变量记录一起,还将type information存储在其中。在这些值中,其中一些是自动分配和/或引用计数的。从Variant变量写入或读取值时,编译器在后台做了很多工作。

varDispatch类型的变量从编译器中获得更多特殊待遇。 varDispatch表示该值的类型为IDispatch(通常,但不一定与Windows COM technology相关)。 IDispatch的实例通过GetTypeInfoCountGetTypeInfo方法提供有关其方法和属性的信息。您可以使用其GetIDsOfNames方法按名称查询信息。

让我们先从您的评论中回答问题:

即使没有用于ToString类型的帮助器,为什么Delphi允许我使用Variant函数?

这就是Delphi如何实现称为late binding的概念。它允许您调用在编译时类型未知的对象的方法。此项工作的前提是基础变体类型支持后期绑定。 Delphi内置了对varDispatchvarUnknown变体的后期绑定的支持,如单元DispInvokeCore中的过程System.Variants所示。

我不明白为什么ToString函数会引发Variant类型变量的异常。

如上所述,在运行时,您的程序尝试对变量值为ToString的变量值调用varByte方法。由于它不支持后期绑定(以及其他序数变体类型),因此会出现异常。

要将变体值转换为字符串,请使用VarToStr

这是将后期绑定与Microsoft Speech API结合使用的简单示例:

uses
  Winapi.ActiveX,System.Win.ComObj;

var
  Voice: Variant;
begin
  CoInitialize(nil);
  try
    Voice := CreateOleObject('SAPI.SpVoice');
    Voice.Speak('Hello,World!');
  finally
    CoUninitialize;
  end;
end.
本文链接:https://www.f2er.com/2297276.html

大家都在问