18

多くのプロパティを公開する COM コンポーネントを使用していVariantますが、これらの値が null になることがあります。これらの値を文字列 (または別の Delphi 型) に変換しようとすると、アプリケーションで次のような例外が発生します。

タイプ (Null) のバリアントをタイプ (String) に変換できませんでした

しかし、.net を使用して同じプロパティを呼び出し、値が null の場合、例外は発生せず、null 値は空の文字列として扱われます。

これらの例外を回避して、Delphi からこれらの null 値を処理する方法はありますか?

前もって感謝します。

4

5 に答える 5

30

NullStrictConvertを False に設定してみてください。

これはグローバル変数であるため、副作用を最小限に抑えるために次のように使用します。

var
  OldNullStrictConvert: Boolean;
begin
  OldNullStrictConvert := NullStrictConvert;
  NullStrictConvert := False;
  try
    // code containing conversions
  finally
    NullStrictConvert := OldNullStrictConvert;
  end;
end;

(実際には、これからガーディアン インターフェイスを作成しました。)

注意: 実行可能な場合は、ウォーレンのようなコードを好みます。

于 2011-05-09T18:34:45.917 に答える
20

受け入れられた回答はグローバル設定を変更し、変更前に機能していた他のコードの操作に意図しない副作用をもたらす可能性があります。

まず、 を使用できます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 ライブラリ コードのデフォルトの動作を「グローバルに変更」しようとするよりも、コードを記述して独自のコードを呼び出す方が優れていることを示したいだけです。

于 2011-05-09T23:04:10.897 に答える
14

これは、文書化された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バリアントでまったく同じ動作を示すため、.NETに関するOPの発言には疑問があります。

于 2011-05-10T02:49:22.510 に答える
7

VarToStr()とは、 Null 値を内部的に明示的にチェックするため、NullをVarToStrDef()に変換する正しい適切な方法です。VariantString

于 2012-05-08T01:48:16.767 に答える
4

..user422039 のコードから、VarToStr を使用しないと、S:=V が暗黙の変換でリレーされ、環境によって異なる結果が生じる可能性があります。

S := VarToStr(V);
or
S := VarToStrDef(V, yourdefaultvalue);
于 2012-02-09T07:55:21.043 に答える