Managing null values in variants using Delphi
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);
精彩评论