文字列を複数に分けて連結する場合、インターンプールとの関係で注意した方がよさそうと思ったことを書きます。(元の話は MSDN Forum のスレッド「ASP.NET MVC で SQL文の塊を静的クラスで宣言することについて」です)
長い文字列を一行で書くと可読性が落ちるので、複数の行に分けて書くいうことがあると思います。
例えば、以下のコードのように、SQL Server に発行するクエリを複数の文字列に分けて、改行して、+ 演算子で連結するというケースを考えてみます。
その際、以下のコードの s2, s3 のようにするのは止めた方がよさそうです。その理由を以下に書きます。
string s0 =
"SELECT aaa, bbb, ccc FROM Table1 WHERE ddd = @ddd";
string s1 = "SELECT aaa, bbb, ccc " +
"FROM Table1 " +
"WHERE ddd = @ddd";
string s2 = "SELECT aaa, bbb, ccc ";
s2 += "FROM Table1 ";
s2 += "WHERE eee = @eee";
// StringBuilder で連結した結果はインターンされない。
// ただし Append の引数の個々の文字列はインターンされる
string s3 = new StringBuilder().
Append("SELECT aaa, bbb, ccc ").
Append("FROM Table1 ").
Append("WHERE fff = @fff").
ToString();
// t1 は "WHERE ddd = @ddd"
string t1 = new StringBuilder().
Append("WHERE ddd "). Append("= @ddd").
ToString();
// t2 は "WHERE eee = @eee"
string t2 = new StringBuilder().
Append("WHERE eee ").Append("= @eee").
ToString();
// t3 は "WHERE fff = @fff"
string t3 = new StringBuilder().
Append("WHERE fff ").Append("= @fff").
ToString();
Console.WriteLine("s0 と s1 は同一オブジェクトを指す: {0}",
(object)s1 == (object)s0);
Console.WriteLine("t1 はインターンされている: {0}",
(string.IsInterned(t1) == null));
Console.WriteLine("t2 はインターンされている: {0}",
(string.IsInterned(t2) == null));
Console.WriteLine("t3 はインターンされている: {0}",
(string.IsInterned(t3) == null));
// 結果は:
// s0 と s1 は同一オブジェクトを指す: True
// t1 はインターンされている: True
// t2 はインターンされている: False
// t3 はインターンされている: False
s0 のコードで文字列 "SELECT aaa, bbb, ccc FROM Table1 WHERE ddd = @ddd" はインターンプールに格納さます。
s1 のコードでは、"SELECT aaa, bbb, ccc ", "FROM Table1 ", "WHERE ddd = @ddd" という複数の文字列に分けて、それらを + 演算子で連結しています。しかしながら、個々の文字列がインターンされることはなく、コンパイラは連結後の結果だけを見て、s0 のコードで生成されインターンされた文字列の参照を s1 に代入するようです。
s0 と s1 は同じオブジェクトを指すこと(即ち、(object)s1 == (object)s0 は true になります)と、StringBuilder で生成した t1("WHERE ddd = @ddd" という文字列)がインターンされてないことがそれを裏付けていると思います。
しかし、s2, s3 の場合、t2, t3 がインターンされているという結果からみると、右辺の個々の文字列のオブジェクトも作られ、それらがインターンプールに格納されるという無駄なことが行われるようです。
ちなみに、インターンプールというのは、文字列を key に、ヒープ上の String オブジェクトのアドレスを value に持つハッシュテーブルのようなものだそうです。詳しくは MSDN ライブラリの記事「String.Intern メソッド」の記事の解説を見てください。
寿命についてもインターンプール特有のものがあるそうです。詳しくは上の記事の「パフォーマンスに関する考慮事項」のセクションを見てください。