我正在使用COM组件,它暴露了很多Variant
属性,但有时这些值为null。当我尝试将这些值转换为字符串(或其他Delphi类型)时,应用程序会引发如下异常:
无法将类型(Null)的变体转换为type(String)
但是如果我使用.net来调用相同的属性并且值为null,则不会引发异常,并且将null值视为空字符串。
我的问题是有一种方法可以从Delphi处理这些空值来避免这些异常吗?
提前致谢。
答案 0 :(得分:28)
尝试将NullStrictConvert设置为False。
由于它是一个全局变量,我使用它如下,以尽量减少副作用:
var
OldNullStrictConvert: Boolean;
begin
OldNullStrictConvert := NullStrictConvert;
NullStrictConvert := False;
try
// code containing conversions
finally
NullStrictConvert := OldNullStrictConvert;
end;
end;
(实际上我已经制作了一个监护人界面。)
注意:在可行的情况下,我更喜欢像Warren这样的代码。
答案 1 :(得分:18)
接受的答案会更改全局设置,并且可能会在更改之前对其他代码的操作产生意外的副作用。
首先你可以使用VarToStrDef
,其次,如果你必须提供除此之外的一些功能,那么我会让我的代码调用我自己的函数MyVarToStr,并按照这样做:
resourcestring
SNilValue = '[nil]';
function VarIsAssigned(v:Variant):Boolean; inline;
begin
result := (v<>Variants.Null) and (not VarIsNull(V));
end;
function MyVarToStr( v:Variant):String;
begin
if VarIsAssigned(v) then
result := VarToStr(v)
else
result := SNilValue;
end;
由于似乎VarToStrDef应该足够了,我只是想证明编写代码并调用自己的代码比尝试“全局更改”VCL / RTL库代码的默认行为更好。
答案 2 :(得分:14)
这是VarToStr
函数的记录行为。没有必要重新发明轮子。
空变体是不同的类型(是的,它是一种类型,而不仅仅是一个值),表示缺失或未知数据。因此,严格说,常规变量动态类型不应与Null
值(illustrated一起发生,并反映在RTL默认值中)。
var
V: Variant;
S: string;
S := VarToStr(V); { stongly-typed explicit conversion }
if not VarIsNull(V) then { program knows what it does, but reproduces RTL behaviour }
S := V
else
S := NullAsStringValue;
NullStrictConvert := False; { smelly, from now on Null variant loses its specifics }
S := V;
try
S := V;
except on Eaten: Exception do { stinky PHP-style, hiding error instead of fixing it }
S := NullAsStringValue;
end;
注意:大多数后期Delphi.NET在Null变种上表现出完全相同的行为,因此OP对.NET的评论是值得怀疑的。
答案 3 :(得分:5)
VarToStr()
和VarToStrDef()
是将Null Variant
转换为String
的正确方法,因为它们会在内部明确检查Null值。
答案 4 :(得分:4)
..来自user422039代码使用VarToStr否则S:= V继承隐式转换,这可能会在不同的环境中产生不同的结果:
S := VarToStr(V);
or
S := VarToStrDef(V, yourdefaultvalue);