stringとobjectを+演算子で連結できたらしい
そんなばかな。
アニソン三昧以来起動していなかったPCを思わず立ち上げて確認。
アニソン三昧以来起動していなかったPCを思わず立ち上げて確認。
string a = "foo"; // string b = a + 123.ToString(); string b = a + 123; // b == "foo123" // var c = "bar" + new KeyValuePair<int, bool>(1, true).ToString(); var c = "bar" + new KeyValuePair<int, bool>(1, true); // c == "bar[1, True]"
ToStringいらないってどういうことなの。
コンパイラの魔法
var test = "foo" + 123;
nop ldstr "foo" ldc.i4.s 123 box [mscorlib]System.Int32 call string [mscorlib]System.String::Concat(object, object) stloc.0
Concatメソッドが呼ばれています。お、おう。
文字列を連結するメソッドとして、String.Concatメソッドがあります。String.Concatメソッドを使ったときと連結演算子を使ったときの違いは、全くありません。ビルドするとどちらもString.Concatが使われるようになります。
http://dobon.net/vb/dotnet/string/concat.html
このメソッドは、arg0 と arg1 のパラメーターなしの ToString メソッドを呼び出すことによって、arg0 と arg1 を連結します。区切り記号は追加しません。
http://msdn.microsoft.com/ja-jp/library/kbseaaft
なるほど。
仕様の言い分
もしString.Concatを使うからobjectを渡せるというのであれば、その旨が仕様にも書いてあるはず。と思って検索するも見つからない。
代わりにこんなものを発見。
- 文字列の連結 :
二項演算子 + のこれらのオーバーロードでは、文字列の連結が実行されます。文字列連結のオペランドが null の場合は、空の文字列に置き換えられます。文字列ではない引数は、object 型から継承された仮想の ToString メソッドを呼び出すことで、文字列形式に変換されます。ToString が null を返す場合は、空の文字列に置き換えられます。
string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);
C#言語仕様 Version4.0§7.8.4加算演算子
なるほど・・・毎回ToStringしてたよ・・・
まとめ
string operator +(string x, string y); string operator +(string x, object y); string operator +(object x, string y);
値型の場合はボックス化されてしまうのでToStringが用意されているなら先にやっておくのがいいですね。ボックス化のコストは馬鹿にならないってばっちゃが。
ついでに本家.NET Frameworkの実装を見ると、一つでもobjectがあれば全てToStringした上で全パラメータstringのオーバーロードに流しているようなので云々。
それにしても「複数の文字列から新しい文字列を生成するには+演算子を使います」といった説明はあっても、object渡せるって説明が仕様以外に見つからなかったのはどういう・・・