开发者

Managing null values in variants using Delphi

开发者 https://www.devze.com 2023-03-05 03:00 出处:网络
I\'m working with a COM component which exposes a lot of Variant properties, but sometimes these values are null. When I try to convert these values to string (or another Delphi type) the application

I'm working with a COM component which exposes a lot of Variant properties, but sometimes these values are null. When I try to convert these values to string (or another Delphi type) the application raises an exception like this:

Could not convert variant of type (Null) into type (String)

But if I use .net to call the same properties and the values are null, no exceptions are raised and the null values are treated as empty strings开发者_运维百科.

My question there is a way to handle these null values from Delphi avoiding these exceptions?

Thanks in advance.


Try setting NullStrictConvert to False.

As it's a global variable I use it like follows to minimize side effects:

var
  OldNullStrictConvert: Boolean;
begin
  OldNullStrictConvert := NullStrictConvert;
  NullStrictConvert := False;
  try
    // code containing conversions
  finally
    NullStrictConvert := OldNullStrictConvert;
  end;
end;

(In reality I have made a guardian interface out of this.)

NB: Where it's feasible I prefer code like Warren's.


The accepted answer changes a global setting, and could have unintended side effects on the operation of other code that was working before you changed it.

First you could just use VarToStrDef, secondly, if you must provide some functionality other than that, then I would have my code call my own function MyVarToStr, and do it like this:

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;

Since it seems that VarToStrDef should be enough, I only mean to demonstrate that it's better to write your code and call your own code, than to try to "globally change" the default behaviour of VCL/RTL library code.


This is a documented behaviour of VarToStr function. There is no need to reinvent a wheel.

Null variant is distinct type (yes, it is a type, not merely a value), which denotes either missing or unknown data. So, strictly speaking, regular variant dynamic-typing should not happen with Null values (illustrated and reflected in RTL defaults).

given:

var
  V: Variant;
  S: string;

better code

S := VarToStr(V);             { stongly-typed explicit conversion }

relatively good code

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

bad code

NullStrictConvert := False;   { smelly, from now on Null variant loses its specifics }
S := V;

even worse code

try
  S := V;
except on Eaten: Exception do { stinky PHP-style, hiding error instead of fixing it }
  S := NullAsStringValue;
end;

NOTE: Most late Delphi.NET exhibits exactly the same behaviour on Null variants, so OP's remark about .NET is questionable.


VarToStr() and VarToStrDef() are the correct and proper way to convert a Null Variant to a String, as they explicitially check for Null values internally.


..from user422039 code use VarToStr otherwise S:=V relays on an implicit conversion which may create different result on different environment:

S := VarToStr(V);
or
S := VarToStrDef(V, yourdefaultvalue);
0

精彩评论

暂无评论...
验证码 换一张
取 消