web-dev-qa-db-ja.com

string = string + int:背後には何がありますか?

C#では、文字列と整数を暗黙的に連結できます。

_string sth = "something" + 0;
_

私の質問は:

  1. なぜ、文字列とintを暗黙的に連結できるという事実を仮定することにより、C#は次のような文字列の初期化を許可しません。

    _string sth = 0; // Error: Cannot convert source type 'int' to target type 'string'
    _
  2. C#が文字列として0をキャストする方法。 0.ToString()または_(string)0_または他の何かですか?

  3. 前の質問の答えを見つける方法は?
49

次のように String.Concat(object, object) の呼び出しにコンパイルされます。

_string sth = String.Concat("something", 0);
_

(この特定の行は、実際にはコンパイラーによって最適化されます)

このメソッドは次のように定義されています:(.Net Reference Sourceから取得)

_    public static String Concat(Object arg0, Object arg1) {
        if (arg0==null) {
            arg0 = String.Empty; 
        }

        if (arg1==null) { 
            arg1 = String.Empty;
        } 
        return Concat(arg0.ToString(), arg1.ToString());
    }
_

(これはString.Concat(string, string)を呼び出します)


これを発見するには、ildasm、またはReflector(ILまたはC#で最適化なし)を使用して、_+_行のコンパイル先を確認します。

51
SLaks

これは、C#4仕様のセクション7.8.4で指定されています。

x + yという形式の操作では、特定の演算子実装を選択するために、バイナリ演算子のオーバーロード解決(§7.3.4)が適用されます。オペランドは、選択した演算子のパラメーター型に変換され、結果の型は演算子の戻り型です。

定義済みの加算演算子を以下にリストします。数値および列挙型の場合、定義済みの加算演算子は2つのオペランドの合計を計算します。一方または両方のオペランドが文字列型の場合、定義済みの加算演算子はオペランドの文字列表現を連結します。

最後の文は、この状況に最も関連するものです。

じゃあ後で:

ストリング連結

string operator +(string x, string y);

string operator +(string x, object y);

string operator +(object x, string y);

バイナリ+演算子のこれらのオーバーロードは、文字列の連結を実行します。文字列連結のオペランドがnullの場合、空の文字列が置換されます。それ以外の場合、型オブジェクトから継承された仮想ToStringメソッドを呼び出すことにより、非文字列引数は文字列表現に変換されます。 ToStringがnullを返す場合、空の文字列が置換されます。

これは、整数を文字列に変換する方法を指定します。

そして結果:

文字列連結演算子の結果は、左のオペランドの文字とそれに続く右のオペランドの文字で構成される文字列です。文字列連結演算子がnull値を返すことはありません。

連結を実行する実際の手段は実装固有ですが、他の回答で述べたように、MS実装はstring.Concatを使用します。

22
Jon Skeet