web-dev-qa-db-ja.com

Delphiを使用したバリアントのnull値の管理

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

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

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

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

前もって感謝します。

18
Salvador

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

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

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

(実際には、これから保護者インターフェイスを作成しました。)

注意:可能であれば、 Warren のようなコードをお勧めします。

28
Uli Gerhardt

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

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

18
Warren P

これは VarToStr 関数の文書化された動作です。ホイールを再発明する必要はありません。

Nullバリアントは特殊タイプ(はい、それは単なる値ではなくタイプです)で、欠落データまたは不明データのいずれかを示します。したがって、厳密にと言えば、通常のバリアントdynamic-typingNullでは発生しないはずです。値( 図示 であり、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のコメントには疑問があります。

14
user422039

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

6
Remy Lebeau

..from user422039コードはVarToStrを使用します。それ以外の場合、S:= Vは暗黙的な変換を中継し、異なる環境で異なる結果を生成する可能性があります。

S := VarToStr(V);
or
S := VarToStrDef(V, yourdefaultvalue);
4
hola