How to tell if a Delphi variant is an empty string?

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-22 04:14:43

问题


Variants are always fun, eh?

I am working on a legacy application that was last in D2007 to migrate it to Delphi XE.

Variants have changed quite a bit in the interim.

This line of code:

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

returned True and exited in D2007, but doesn't in Delphi XE.

I have changed it to this:

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

I'm not convinced this is the "best" way to go. The Variants unit doesn't have a specific call to do this, and I certainly recall this being an issue for folks in the past. However, a search revealed no library function or any other accepted way.

Is there a "correct" or better way?


回答1:


Updated: String-specific to avoid exceptions:

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

Update3: If you want better performance and less string heap memory waste try this. Imagine that the strings are 64K in length. The code above does a VarToStr and allocates perhaps 64K of UnicodeString heap space to hold the data, just so we can just look for the nul terminator at the end of the string for BSTR, and for nil-pointers for other types.

The code below is a slightly odd in that one does not commonly reach into the internal representation of variants, but David pointed out the bugs and I re-re-tested it and it seems to work, although no warranty is expressed or implied. A unit test for this puppy would be good. At some future date if Delphi RTL gods decided to rename the internal representation of the Variant structure fields, the code below would need to be changed.

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:


VarIsStr is a perfectly plausible way to do it. This is implemented as:

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;

The change you are seeing is, of course, really due to the Unicode changes in D2009 rather than changes to variants. Your string will be varUString, aka UnicodeString. Of course, VarIsStr also picks up AnsiString/varString and WideString/BSTR/varOleStr.

If you want a truly faithful conversion of your Delphi 2007 code then you would write:

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

Exactly what you need to do, only you can know, but the key thing is that you have to account for the newly arrived varUString.




回答3:


Variants can be a Number or a String.

There might be a problem when the Variant (Number) has a negative value (-15).

Also your line

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

I always have to put ( )

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



回答4:


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

Does the trick for me.



来源:https://stackoverflow.com/questions/9673827/how-to-tell-if-a-delphi-variant-is-an-empty-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!