String 如何判断Delphi变量是否为空字符串?
变种总是很有趣的,是吗 我正在开发一个遗留应用程序,该应用程序上一次是在D2007中将其迁移到Delphi XE 在此期间,变体发生了相当大的变化 这行代码:String 如何判断Delphi变量是否为空字符串?,string,delphi,delphi-xe,variants,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; 我不相
if (VarType(Value) = varString) and (Value = '') then
Exit;
返回True并在D2007中退出,但在Delphi XE中没有
我已将其更改为:
if VarIsStr(Value) and (VarToStr(Value) = '') then
Exit;
我不相信这是最好的方式。变体部门没有具体的要求来做这件事,我当然记得这是过去人们的一个问题。然而,一项搜索显示没有任何库函数或任何其他被接受的方式
是否有“正确”或更好的方法?更新:特定于字符串以避免异常:
if VarIsStr(Value) and (Length(VarToStr(v))=0) then ...
更新3:如果你想要更好的性能和更少的字符串堆内存浪费,试试这个。
假设字符串的长度为64K。上面的代码执行一个VarToStr并分配64K的UnicodeString堆空间来保存数据,这样我们就可以在BSTR的字符串末尾查找nul终止符,在其他类型中查找nil指针
下面的代码有点奇怪,因为通常不涉及变体的内部表示,但是David指出了错误,我重新测试了它,它似乎可以工作,尽管没有明示或暗示任何保证。这只小狗的单元测试会很好。在将来的某个日期,如果Delphi RTL gods决定重命名变量结构字段的内部表示,则需要更改下面的代码
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;
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/varString
和WideString/BSTR/varOleStr
如果您希望真正忠实地转换您的Delphi 2007代码,那么您可以编写:
if (VarType(Value) = varUString) and (Value = '') then
Exit;
确切地说,您需要做什么,只有您自己知道,但关键是您必须考虑新到达的
varUString
变体可以是数字或字符串
当变量(数字)的值为负值(-15)时,可能会出现问题
还有你的线路
(VarType(Value) = varString) and (Value = '')
((VarType(Value) = varString) and (Value = ''))
我总是要把(
)
这是我的窍门。Nick试图避免变体无法强制为字符串时出现的异常。这就是他需要第一次检查和短路评估的原因。我很难看到所有额外的复杂性带来了什么。对于空的OleStr,它也会给出一个错误的答案,因为它们被表示为一个空的wchar\t。还是我弄错了?与“”进行比较有什么不好?除非你用VartoString将其展平到一个单位分解,否则它并不总是有效。打个比方,这就像一个接一个地数你所有的便士,以确保你有。这是不必要和浪费的。这里所谓的优化在我看来显然是不成熟和毫无意义的。以这种方式编写代码会导致错误。你心照不宣地接受了这一点,说你可能错过了一些小案子。对我来说,编写如此复杂的代码,以至于您无法确定其正确性,这是毫无意义的。尤其是当存在琐碎且明显正确的替代方案时。另一方面,显然@Nick更喜欢这种方式,所以我可能会错过一些东西。请给我一个解释。
strlen
太浪费了。走这条线没有意义。我已经自由地以一种有效的方式进行了编辑。我还是觉得感觉像是预科生。但是你看顺便说一句,v=''
是真的,如果我显式地将其分配给v:=''代码>-我猜有不止一个变量字符串子类型,可能是B_STR和其他类型,因此元素比较失败,即使内容是相同的。如果VarToStr(Value)=''
单独完成工作,@kobik这会失败吗?例如,当Value
等于Null
@DavidHeffernan,按照D5/D7中的预期工作。e、 g.如果VarToStr(Null)='',那么beep
@kobik Null不是一个字符串,因为它不是一个字符串。您误解了这个问题。负数在这里不相关。关于()的第二点也是完全错误的。当value
不是字符串时,所有情况都默认为true。这一逻辑与问题不符。
if VarToStrDef(value, '') = '' then