Подтвердить что ты не робот

Управление нулевыми значениями в вариантах с помощью Delphi

Я работаю с COM-компонентом, который предоставляет множество свойств Variant, но иногда эти значения равны нулю. Когда я пытаюсь преобразовать эти значения в строку (или другой тип Delphi), приложение вызывает исключение, подобное этому:

Не удалось преобразовать вариант типа (Null) в тип (String)

Но если я использую .net для вызова тех же свойств, и значения равны нулю, исключений не возникает, а нулевые значения рассматриваются как пустые строки.

В моем вопросе есть способ справиться с этими нулевыми значениями из Delphi, избегая этих исключений?

Спасибо заранее.

4b9b3361

Ответ 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 внутри.