今日は「実は Visual Studio 17.1 Preview 1 (先月) の時点で既に入ってた」という機能の話。
C# 11 で、$"{ここ}"
みたいな「補完穴」(interpolation hole: 補完文字列の {}
の中)の改行に関する仕様がちょっと変わります。
文字列リテラル中の改行
C# の文字列リテラルは、@
を付けると逐語的(\
を使ったエスケープをしなくなる)になって、その中には改行を直接入れることができます。
// @ を付けると文字列内での改行 OK になる。
var s1 = ""; // 改行入れれない。
var s2 = @"
"; // 改行 OK。
var s3 = "
"; // 当然これはコンパイル エラー。
この仕様、補間文字列に対しても同様です。
// @ を付けると文字列内での改行 OK になるのは $"" でも一緒。
var x = 123;
var s1 = $"{x}"; // 改行入れれない。
var s2 = @$"
{x}
"; // 改行 OK。
var s3 = $"{x}
"; // 当然これはコンパイル エラー。
補間穴中の改行
C# はほぼ全ての構文で改行の有無を問わないので、例えば以下の2つのコードは全く同じ意味になります。
var x = 123 + 987;
var
x
=
123
+
987
;
で、補間穴 ({}
)の中は普通の C# 構文になります。
前述のような「改行の有無を問わない」という常識に照らし合わせると、
以下のようなコードを書けていいはずです。
(C# 10 まではなぜかダメ。)
// なぜかダメだったコード。
var x = 123;
var s1 = $"{
x
}";
ちなみに、これに @
を付けると C# 10 でもコンパイルできます。
というか、さらに言うと割かし何でも書けます。
//
コメントすら書けます。
// @ を付ければなぜか OK。
var x = 123;
var s1 = $@"{
x
+
987 // コメントすら OK
}";
C# 11 での変更
で、まあ、$"{}"
と $@"{}"
で挙動が違うの、
仕様的にもそうなってるらしいんですが、
中の人曰く「改行を禁止した実際の理由、覚えてない」とのこと。
挙動が違うのも変なのでさらっと直したみたいです。 気づいたタイミング的に C# 10 正式リリースには間に合わなかったものの、 ほぼ修正は終わってたみたいで、即座に merge、実は 17.1 Preview 1 には入っていたみたいです。
ということで、実は LangVersion preview を入れればもう動くらしい。
(このスクショは Visual Studio 17.1.0 Preview 1.1 で撮影。)
さよなら、LangVersion default。おかえり、preview (1年ぶり2度目)。
ということで、以下のようなコード、C# 11 候補になっていて、 preview 指定すると現在でもコンパイルできたりします。
// C# 11 候補。
var x = 123;
var s1 = $"こっちは C# 11 から OK {
x
+
987 // コメントすら OK
}";
var s2 = $@"こっちは元から OK
{
x
+
987 // コメントすら OK
}
def";
と言うのを昨日の Pull Request を見て初めて気づいたという話でした。