8

バリエーションはいつも楽しいですよね?

DelphiXEに移行するためにD2007で最後に使用されたレガシーアプリケーションに取り組んでいます。

その間にバリアントはかなり変更されました。

このコード行:

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

Trueを返し、D2007で終了しましたが、DelphiXEでは終了しません。

私はそれをこれに変更しました:

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

これが「最善の」方法であると私は確信していません。Variantsユニットには、これを行うための特定の呼び出しはありません。これは、過去の人々にとって問題であったことを確かに思い出します。ただし、検索の結果、ライブラリ関数やその他の受け入れられている方法は見つかりませんでした。

「正しい」またはより良い方法はありますか?

4

4 に答える 4

13

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;

もちろん、表示されている変更は、バリアントへの変更ではなく、D2009でのUnicodeの変更によるものです。あなたの文字列はvarUString、別名になりUnicodeStringます。もちろん、VarIsStrピックアップしAnsiString/varStringWideString/BSTR/varOleStr

Delphi 2007コードの真に忠実な変換が必要な場合は、次のように記述します。

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

正確にあなたがする必要があること、あなただけが知ることができます、しかし重要なことはあなたが新しく到着したことを説明しなければならないということですvarUString

于 2012-03-12T19:54:46.337 に答える
4

更新:例外を回避するための文字列固有:

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

Update3:パフォーマンスを向上させ、文字列ヒープのメモリの浪費を減らしたい場合は、これを試してください。文字列の長さが64Kであると想像してください。上記のコードはVarToStrを実行し、データを保持するためにおそらく64KのUnicodeStringヒープスペースを割り当てます。これにより、BSTRの場合は文字列の最後にあるnulターミネーターを、他のタイプの場合はnilポインターを探すことができます。

以下のコードは、バリアントの内部表現に一般的に到達しないという点で少し奇妙ですが、Davidがバグを指摘し、再テストしたところ、保証は明示または暗示されていませんが、機能しているようです。この子犬のユニットテストは良いでしょう。将来、Delphi RTLの神々がバリアント構造フィールドの内部表現の名前を変更することを決定した場合、以下のコードを変更する必要があります。

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;
于 2012-03-12T19:54:45.157 に答える
0

バリアントは、数値または文字列にすることができます。

バリアント(数値)の値が負(-15)の場合、問題が発生する可能性があります。

またあなたのライン

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

私はいつも入れなければなりません( )

((VarType(Value) = varString) and (Value = ''))
于 2012-03-12T23:21:07.427 に答える
-1
if VarToStrDef(value, '') = '' then

私のためにトリックをします。

于 2014-09-11T09:06:00.693 に答える