Как определить, является ли вариант Delphi пустой строкой?

Варианты это всегда весело, а?

Я работаю над устаревшим приложением, которое было последним в D2007 для его миграции на Delphi XE.

Варианты немного изменились за это время.

Эта строка кода:

if (VarType(Value) = varString) and (Value = '') then 
  Exit;

вернул True и вышел в D2007, но не в Delphi XE.

Я изменил это на это:

if VarIsStr(Value) and (VarToStr(Value) = '') then
    Exit;

Я не уверен, что это "лучший" путь. Подразделение Variants не имеет специального вызова, чтобы сделать это, и я, конечно, помню, что это было проблемой для людей в прошлом. Однако поиск не выявил библиотечной функции или какого-либо другого принятого способа.

Есть ли "правильный" или лучший способ?

5 ответов

Решение

Обновлено: специфично для строки, чтобы избежать исключений:

    if VarIsStr(Value) and (Length(VarToStr(v))=0) then ...

Обновление 3: если вам нужна лучшая производительность и меньше потерь памяти в куче строк, попробуйте это. Представьте себе, что строки имеют длину 64 КБ. Приведенный выше код выполняет VarToStr и выделяет, возможно, 64 КБ пространства кучи UnicodeString для хранения данных, просто чтобы мы могли просто искать нулевой терминатор в конце строки для BSTR и нулевые указатели для других типов.

Приведенный ниже код немного странный, поскольку он обычно не затрагивает внутреннее представление вариантов, но Дэвид указал на ошибки, и я повторно проверил его, и, похоже, он работает, хотя никаких гарантий не выражено и не подразумевается. Юнит тест для этого щенка был бы хорош. Когда-нибудь в будущем, если боги Delphi RTL решат переименовать внутреннее представление полей структуры Variant, приведенный ниже код необходимо будет изменить.

function VarStrEmpty(v:Variant):Boolean;
var
  data:PVarData;
begin
    data := FindVarData(V);
  case data^.VType of
     varOleStr:
            result := (data^.VOleStr^=#0);
     varString:
            result := (data^.VString=nil);
     varUString:
            result := (data^.VUString=nil);
     else
      result := false;
  end;
end;

VarIsStr это вполне правдоподобный способ сделать это. Это реализовано как:

function VarTypeIsStr(const AVarType: TVarType): Boolean;
begin
  Result := (AVarType = varOleStr) or (AVarType = varString)
    or (AVarType = varUString);
end;

function VarIsStr(const V: Variant): Boolean;
begin
  Result := VarTypeIsStr(FindVarData(V)^.VType);
end;

Изменения, которые вы видите, действительно связаны с изменениями Unicode в D2009, а не с вариантами. Ваша строка будет varUStringака UnicodeString, Конечно, VarIsStr также забирает AnsiString/varString а также WideString/BSTR/varOleStr,

Если вы хотите действительно точное преобразование кода Delphi 2007, вы должны написать:

if (VarType(Value) = varUString) and (Value = '') then 
  Exit;

Точно, что вам нужно сделать, только вы можете знать, но главное, что вы должны учитывать вновь прибывших varUString,

Варианты могут быть числом или строкой.

Может возникнуть проблема, когда вариант (число) имеет отрицательное значение (-15).

Также ваша линия

(VarType(Value) = varString) and (Value = '')

Я всегда должен поставить ()

((VarType(Value) = varString) and (Value = ''))

Попытался ли ты

      if VarSameValue(Value, '') then 
  Exit;
if VarToStrDef(value, '') = '' then

Делает трюк для меня.

Другие вопросы по тегам