Как определить, является ли вариант Delphi пустой строкой? - PullRequest
8 голосов
/ 12 марта 2012

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

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

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

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

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

вернула True и завершилась в D2007, но не в Delphi XE.

Я изменил это на следующее:

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

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

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

Ответы [ 4 ]

12 голосов
/ 12 марта 2012

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.

3 голосов
/ 12 марта 2012

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

    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;
0 голосов
/ 11 сентября 2014
if VarToStrDef(value, '') = '' then

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

0 голосов
/ 13 марта 2012

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

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

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

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

Мне всегда нужно ставить ( )

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