Управление нулевыми значениями в вариантах с помощью Delphi
Я работаю с COM-компонентом, который предоставляет множество свойств Variant
, но иногда эти значения равны нулю. Когда я пытаюсь преобразовать эти значения в строку (или другой тип Delphi), приложение вызывает исключение, подобное этому:
Не удалось преобразовать вариант типа (Null) в тип (String)
Но если я использую .net для вызова тех же свойств, и значения равны нулю, исключений не возникает, а нулевые значения рассматриваются как пустые строки.
В моем вопросе есть способ справиться с этими нулевыми значениями из Delphi, избегая этих исключений?
Спасибо заранее.
Ответы
Ответ 1
Попробуйте установить NullStrictConvert в значение False.
Поскольку это глобальная переменная, я использую его следующим образом, чтобы минимизировать побочные эффекты:
var
OldNullStrictConvert: Boolean;
begin
OldNullStrictConvert := NullStrictConvert;
NullStrictConvert := False;
try
// code containing conversions
finally
NullStrictConvert := OldNullStrictConvert;
end;
end;
(В действительности, я сделал из этого интерфейс опекуна.)
NB: Где это возможно, я предпочитаю код типа Warren.
Ответ 2
Принятый ответ изменяет глобальную настройку и может иметь непреднамеренные побочные эффекты для работы другого кода, который работал до того, как вы его изменили.
Сначала вы могли бы просто использовать 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.
Ответ 3
Это документированное поведение VarToStr
. Нет необходимости изобретать велосипед.
Нулевой вариант - это отдельный тип (да, это тип, а не просто значение), что означает либо отсутствующие, либо неизвестные данные. Итак, говоря строго, регулярный вариант динамического ввода не должен происходить с Null
значениями (показан и отражен в 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 является сомнительным.
Ответ 4
.. из user422039 используется код VarToStr, иначе S: = V-реле при неявном преобразовании, которое может создавать разные результаты в другой среде:
S := VarToStr(V);
or
S := VarToStrDef(V, yourdefaultvalue);
Ответ 5
VarToStr()
и VarToStrDef()
- правильный и правильный способ преобразования Null Variant
в String
, поскольку они явно проверяют значения Null внутри.