sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

C# 8.0 のよく使いそうな新機能まとめ

VisualStudio 2019 の発表イベント にあわせて Visual Studio 2019 も GA (general availiable) になったようです。C# 8.0 の新機能をコーディングする方法をまとめて勉強してみました。(全部ではないですが、使えそうなのから)

使えそうなのからというのも、C# 8.0 は まだ「Preview です。Visual Studio 2019 の GA とは別の扱いです。下記のコメントにあるように正式リリースは .NET Core 3.0 にあわせる予定みたい 1 ですが、そのタイミングは「今年の後半」らしい 2 です。5月にわかるといいですね。

ともかく、今年の後半までに C# 8.0 の使いかたをマスターしておいたほうがよいのは間違いないと思うので、さわりから勉強をはじめました。現時点では機能ごとに安定度が違っていて、使っていい機能もあるという意見もあったので、よさそうな機能から練習をはじめたわけです。

C# 8.0 の新機能(よく使いそうなものまとめ)

  • 新しい switch 式
  • パターンマッチング
  • 静的ローカル関数
  • 暗黙的 using 句
  • null 合体代入演算子 (??=)
  • 文字列の挿入式 ($) と逐語的文字列 (@) の組み合わせ

とりあえず、新しい機能を確認するために、最初に目を通すところは「Github - Language Feature Status」でいいと思う。

練習環境は「sharplab.io」を利用しました。C# のバージョンを選ぶことができるのが特徴で、動作結果を確認する+どういうネイティブコードが出力されたかも確認できる。ウェブ上でコードのテストは「paiza」とかのサイトでもできますが、C# だと sharplab が一番つかえると思います。(というか、新機能を試す意味では、ここ以外無いと思う)

f:id:shikaku_sh:20190405140224p:plain:w400
hello world

スタンダードな使いかたは Results を「Run」に切り替えて、左のコードを入力するエリアに Main メソッドを追加したところからスタート。すこしずつ、「C#」とか「IL」とかの結果を読むようにすると+αの理解が増える。

新しい switch 式

文法に case と break が消えたおかげで、可読性が高くて使いやすそうだし、変数に対して直接 switch で代入できるのは、便利。これは問題なく実用していく。"_" はなんでもマッチングするので、最後にいれておくことになる。

「変数名 switch { ... }」と書くからステートメントの switch を後ろに書く変わった記法になっている。もともとは「switch (変数名) { case ... } 」だったわけで、違和感はある。
ただ、変数に直接入れる上記の例みたいなのだと、むしろ見やすいと思ったので慣れたら問題なさそう。

switch 式+パターンマッチング

パターンマッチングと組み合わせるとこうなる。C# 8.0 からは複雑なパターンマッチングに対応しているので、プロパティの値でもマッチングができるようになっている。 a4 の出力結果は "A = 10" になる。"A=10" と "B=10" と最後の3つにマッチングしているけど、上から順なので "A = 10"。

静的ローカル関数

issue はこれだと思う。静的ローカル「変数」ではなくて、静的ローカル「関数」が追加されている。コメントアウトしてある部分の、x1 を func2 は式の中で使うことができない。
それを明示するための static ということです。

なにが目的なのかよくわからなかったので、issue を開いてみると、1行目に書いてあること 3 が目的なのかなと。
この提案を最初にあげた jcouv さんの次のコメントを補足しておけば、大体の要旨はつかんでおけると思った。

The primary motivation for this proposal is readability/maintainability. Knowing that some code is isolated makes it easier to understand, review and re-use. That's the same general argument as with any kind of isolation like object encapsulation or functional programming.

暗黙的 using 句

issue はこれだと思う。using 句のネストが深くなって汚くなるんで、Dispose のタイミングは変数のスコープと同じにしたいみたいな意図。

Dispose が読み出される順番は変数の宣言をした順番とは逆の順番になる。例えば Connection と Command の関係は Connection が親で、Command が子だとすると、親を new してから子を new するし、子を破棄してから親を破棄する。すこしどうしてだろうと思ったけど、実際的な挙動なのだと思います。

null 合体代入演算子

issue はこれだと思う。これは、単純だけどとても便利だと書いてあるとおりで、書くのが楽になるから追加された機能でいいと思う。

提案されている名前は (null-coalescing assignment operator) になっているけど、日本語だと null 合体代入演算子とかになるのか。

文字列の挿入式 ($) と逐語的文字列 (@) の組み合わせ

issue はこれだと思う。名前がすごいことになっている (Alternative interpolated verbatim strings) から何事かと思ったけど、C# 6.0 で追加された 文字列挿入(string interpolation) と逐語的文字列リテラル (verbatim string literals) の組み合わせ。便利になりました。

最後のテキストのように複数行の文字列入力ができるようになっているのも新しい機能。ただ、$@ のあとの改行もしっかり残っているし、インデントのスペースの扱いがなんともで、うまくいかないものだなと。
行頭のスペースや改行を無くしたり、ひとつにしたりする Linux みたいなユーティリティメソッドを用意しておくと便利かも。

参考

Effective C# 6.0/7.0

Effective C# 6.0/7.0

Effective C# 4.0

Effective C# 4.0


  1. The current plan is that C# 8.0 will ship at the same time as .NET Core 3.0. (Building C# 8.0 - .NET Blog)

  2. We plan to ship .NET Core 3.0 in the second half of 2019. We will announce the ship date at the Build 2019 conference. (Announcing .NET Core 3 Preview 3 - .NET Blog)

  3. The proposal is to declare a local function as non-capturing. The keyword to indicate that would be static.