Как определить, является ли вариант 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 = ''))