使用Delphi管理变体中的空值

Sal*_*dor 18 delphi null delphi-xe variants

我正在使用COM组件,它暴露了很多Variant属性,但有时这些值为null.当我尝试将这些值转换为字符串(或其他Delphi类型)时,应用程序会引发如下异常:

无法将类型(Null)的变体转换为类型(String)

但是,如果我使用.net来调用相同的属性并且值为null,则不会引发异常,并且将null值视为空字符串.

我的问题是有一种方法可以从Delphi处理这些空值来避免这些异常吗?

提前致谢.

Uli*_*rdt 29

尝试将NullStrictConvert设置为False.

因为它是一个全局变量,我使用它如下,以尽量减少副作用:

var
  OldNullStrictConvert: Boolean;
begin
  OldNullStrictConvert := NullStrictConvert;
  NullStrictConvert := False;
  try
    // code containing conversions
  finally
    NullStrictConvert := OldNullStrictConvert;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

(实际上,我已经制作了一个监护人界面.)

注意:在可行的情况下,我更喜欢沃伦的代码.

  • +1谢谢.只知道这存在是有帮助的. (2认同)
  • 是的,知道是好的,但我个人认为**严格** (2认同)

War*_* P 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;
Run Code Online (Sandbox Code Playgroud)

因为它似乎VarToStrDef应该够了,我只意味着,以证明这是更好地编写代码,并呼吁自己的代码,而不是试图"全球变化"的VCL/RTL代码库的默认行为.


use*_*039 14

这是记录的VarToStr函数行为.没有必要重新发明轮子.

空变量是不同类型(是的,它是一种类型,而不仅仅是一个值),表示缺失或未知数据.因此,严格来说,常规变量动态类型不应该与Null值一起发生(在RTL默认值中说明和反映).

给定:

var
  V: Variant;
  S: string;
Run Code Online (Sandbox Code Playgroud)

更好的代码

S := VarToStr(V);             { stongly-typed explicit conversion }
Run Code Online (Sandbox Code Playgroud)

比较好的代码

if not VarIsNull(V) then      { program knows what it does, but reproduces RTL behaviour }
  S := V
else
  S := NullAsStringValue;
Run Code Online (Sandbox Code Playgroud)

糟糕的代码

NullStrictConvert := False;   { smelly, from now on Null variant loses its specifics }
S := V;
Run Code Online (Sandbox Code Playgroud)

更糟糕的代码

try
  S := V;
except on Eaten: Exception do { stinky PHP-style, hiding error instead of fixing it }
  S := NullAsStringValue;
end;
Run Code Online (Sandbox Code Playgroud)

注意:大多数后期Delphi.NET在Null变体上表现出完全相同的行为,因此OP对.NET的评论是值得怀疑的.


Rem*_*eau 6

VarToStr()并且VarToStrDef()是一个空转换的正确和适当的方式VariantString,因为他们explicitially检查空值内.