如何判断Delphi变量是否为空字符串?

时间:2012-03-12 19:50:24

标签: string delphi delphi-xe variants

变种总是很有趣,是吗?

我正在研究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 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:3)

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

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

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

下面的代码有点奇怪,因为一个人通常不会进入变体的内部表示,但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;

答案 2 :(得分:0)

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

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

也是你的行

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

我总是要( )

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

答案 3 :(得分:-1)

if VarToStrDef(value, '') = '' then

我的诀窍。