nullをキャストすると、Convert.ToString(null)が異なる値を返すのはなぜですか?


116
Convert.ToString(null)

戻り値

null

私の期待通りに。

だが

Convert.ToString(null as object)

戻り値

""

これらはなぜ違うのですか?

回答:


143

ToStringここに登場するオーバーロードが2つあります

Convert.ToString(object o);
Convert.ToString(string s);

C#コンパイラは基本的に、入力を処理する最も具体的なオーバーロードを選択しようとします。null値は、任意の参照型に変換可能です。この場合stringはより具体的であるobjectため、勝者として選択されます。

では、null as object式のタイプをとして固めましたobject。つまり、stringオーバーロードとの互換性がなくなり、コンパイラがobjectのみが残っているオーバーロードをます。

この引き分けの仕組みの非常に複雑な詳細は、C#言語仕様のセクション7.4.3で説明されています。


15
OK。つまり、他のオーバーロードではなく、1つのオーバーロードを使用しています。理にかなっています。しかし、両方のオーバーロードが同じものを返すべきではありませんか?+1 btw。
John MacIntyre

2
@JohnMacIntyre-それはコンパイラではなく開発チームに依存します。
JonH 2012

8
@JohnMacIntyreあなたがConvert.ToString(string)それの実装を見ると、Convert.ToString(object)実際には追跡するのが難しいパスを通過するときのアイデンティティ関数です。一見して同じように返す必要があることに同意しますが、BCLのコンバーチブルレイヤーは私がよく知っているものではなく、その違いには十分な理由がある可能性があります(私は懐疑的です)
JaredPar

nullオブジェクトをnull文字列に変換する方法を探してここに来ました。他の検索者の答えは(string)null、またはオブジェクトがoと呼ばれる場合(string)o
rayzinnz

65

続きJaredParの優れたオーバーロードの解決の答え-質問は「なぜままConvert.ToString(string)リターンヌルが、Convert.ToString(object)リターンはstring.Empty」?

そして、その答えは...ので、ドキュメントが言うように

Convert.ToString(string)は、「指定された文字列インスタンスです。実際の変換は実行されません。」

Convert.ToString(object)は、「値の文字列表現、または値がnullの場合はString.Empty」を返します。

編集:これが「仕様のバグ」、「非常に悪いAPI設計」、「なぜこのように指定されたのか」などかどうかについて-表示されない理由について、いくつかの根拠で説明しますそれは大したことです。

  1. System.Convertすべての基本型をそれ自体に変換するメソッドがあります。これは奇妙です-変換が必要ない、または可能でないため、メソッドは最終的にパラメーターを返すだけです。Convert.ToString(string)同じように動作します。私はこれらがコード生成シナリオのためにここにあると思います。
  2. Convert.ToString(object)渡されnullたときに3つの選択肢があります。スロー、nullを返す、またはstring.Emptyを返します。スローは悪いことです-生成されたコードにこれらが使用されると仮定すると、二重にそうなります。nullを返すには、呼び出し元がnullチェックを行う必要があります。これも、生成されたコードではあまり適していません。string.Emptyを返すのは妥当な選択のようです。残りのSystem.Convertは、デフォルト値を持つ値タイプ扱います。
  3. nullを返す方が「正しい」かどうかは議論の余地がありますが、string.Emptyの方が確実に使いやすくなっています。変更とConvert.ToString(string)は、「実際の変換なし」のルールを破ることを意味します。以来、System.Convert静的ユーティリティクラスであり、各メソッドは、論理的にそれ自身として扱うことができます。この振る舞いが「意外」であるはずの現実世界のシナリオはほとんどないので、ユーザビリティを(可能性のある)正確さに勝ち取ってみましょう。

それが仕様のバグだと言ってもいいのでしょうか?
John MacIntyre

3
それがなぜこのようなものであるかは答えません。このように動作することが文書化されているため、このように動作するとはトートロジーです。
CodesInChaos

2
@JohnMacIntyre IMO非常に悪いAPIデザインだと言っても過言ではありません。
CodesInChaos

7
@CodeInChaos-トートロジーではありません。ただし、BCLが開発された後の観察可能な動作に基づいてドキュメントが記述されていると想定しない限り。それは奇妙な仮定になると思います。IOW、「このように動作することが文書化されている」ではなく、「このように動作すること記載されている」-つまり、「このように動作するように指定されている」。
Mark Brackett 2012

8
それは、質問を「なぜこのように動作するように指定されたのか」にシフトするだけです
CodesInChaos
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.