8

变种总是很有趣,是吗?

我正在开发一个在 D2007 中最后一次将其迁移到 Delphi XE 的遗留应用程序。

在此期间,变体发生了很大变化。

这行代码:

if (VarType(Value) = varString) and (Value = '') then 
  Exit;

返回 True 并在 D2007 中退出,但在 Delphi XE 中没有。

我已将其更改为:

if VarIsStr(Value) and (VarToStr(Value) = '') then
    Exit;

我不相信这是“最好的”方式。Variants 部门没有具体的要求来执行此操作,我当然记得这是过去人们的问题。但是,搜索显示没有库函数或任何其他可接受的方式。

有没有“正确”或更好的方法?

4

4 回答 4

13

VarIsStr是一种完全合理的方法。这被实现为:

function VarTypeIsStr(const AVarType: TVarType): Boolean;
begin
  Result := (AVarType = varOleStr) or (AVarType = varString)
    or (AVarType = varUString);
end;

function VarIsStr(const V: Variant): Boolean;
begin
  Result := VarTypeIsStr(FindVarData(V)^.VType);
end;

当然,您看到的变化实际上是由于 D2009 中的 Unicode 变化,而不是变体的变化。你的字符串将是varUString,又名UnicodeString。当然,VarIsStr也拿起AnsiString/varStringWideString/BSTR/varOleStr

如果您想要真正忠实地转换您的 Delphi 2007 代码,那么您可以编写:

if (VarType(Value) = varUString) and (Value = '') then 
  Exit;

具体需要做什么,只有你自己知道,但关键是新来的你要考虑清楚varUString

于 2012-03-12T19:54:46.337 回答
4

更新:特定于字符串以避免异常:

    if VarIsStr(Value) and (Length(VarToStr(v))=0) then ...

Update3:如果你想要更好的性能和更少的字符串堆内存浪费,试试这个。假设字符串的长度为 64K。上面的代码执行 VarToStr 并分配可能 64K 的 UnicodeString 堆空间来保存数据,这样我们就可以在字符串末尾为 BSTR 查找 nul 终止符,为其他类型查找 nil 指针。

下面的代码有点奇怪,因为它通常不涉及变体的内部表示,但 David 指出了这些错误,我重新测试了它,它似乎可以工作,尽管没有明示或暗示的保证。对这只小狗进行单元测试会很好。在未来某个日期,如果 Delphi RTL 之神决定重命名 Variant 结构字段的内部表示,则需要更改下面的代码。

function VarStrEmpty(v:Variant):Boolean;
var
  data:PVarData;
begin
    data := FindVarData(V);
  case data^.VType of
     varOleStr:
            result := (data^.VOleStr^=#0);
     varString:
            result := (data^.VString=nil);
     varUString:
            result := (data^.VUString=nil);
     else
      result := false;
  end;
end;
于 2012-03-12T19:54:45.157 回答
0

变体可以是数字或字符串。

当 Variant (Number) 具有负值 (-15) 时可能会出现问题。

还有你的线

(VarType(Value) = varString) and (Value = '')

我总是要放( )

((VarType(Value) = varString) and (Value = ''))
于 2012-03-12T23:21:07.427 回答
-1
if VarToStrDef(value, '') = '' then

对我有用。

于 2014-09-11T09:06:00.693 回答