また前回記事の続きです。C#は5.0,6.0 みたいに1ずつバージョンが上がっていたのですが、なぜか7系だけ7.1, 7.2, 7.3みたいな上がり方をしています。なので記事を分けました。
今回はC# 7.1
を見ていきます。下記ページを見ながら書いていきます。
C# バージョン 7.1
async Main
メソッド
Main
メソッド(プログラムのエントリポイントなるメソッド)にasync
を付けられるようになりました。
= Main
メソッドでawait
キーワードを使用できるようになりました。
using System; using System.Threading.Tasks; namespace CSharp71 { class Program { static async Task Main(string[] args) { await Task.Run(() => Console.WriteLine("Run async method.")); Console.WriteLine("Hello World!"); } } }
Main
メソッドが満たすべき要件はこちらに記載があります。以下の二つが増えています。
Main の戻り値の型は、void または int のいずれかになります。C# 7.1 以降では Task または Task
になる場合もあります。 Main で Task または Task
が返される場合に限り、Main の宣言に async 修飾子を含めることができます。
ちなみに、C#7.0以前のように戻り値Task
を認めないバージョンで戻り値をTask
にしたMainメソッドを定義した場合、プロジェクトファイルからMainメソッドの条件を満たすメソッドが無くなることから、コンパイルエラーが発生します。発生するエラーはこちらのCS5001
です。有効なMainメソッドがないよ、というエラーです。
なお、プロジェクトのC#バージョンを指定するには、.csproj
ファイルにLangVersion
の指定を入れます。
例:CSharpSample/CSharp70.csproj at master · piroron/CSharpSample · GitHub
async Main
が書けないのは、コマンドラインアプリでは不便極まりないので、便利になった改訂だなと思いました。
default
リテラル式
default
演算子は、default(int)
のように、括弧で指定した型の初期値を生成するものでした。これが拡張されて、型が推測できる場合は括弧を省略できるようになりました。
class DefaultLiteral { public DefaultLiteral() { // NG // var value = default; // OK int value = default; } }
特定の条件で戻り値をその型のデフォルト値にする、というケースでコードがちょっと簡潔になるので良いのかなと。
推論されたタプル要素の名前
タプルの前に宣言した変数をタプルの要素とした場合、そのままタプル要素の名前として使用できるようにした、ということみたいです。
class TupleInitialize { public TupleInitialize() { int x = 10; Action y = () => Console.WriteLine("Run something."); var pair = (x, y); pair.y(); // C#7.0だとこれが推論できない } }
C#7.0のソースでも問題なくコンパイル通るようですが…何か間違っているかもしれません。
ジェネリック型パラメーターのパターン マッチ
メソッドのパラメータがジェネリック型である場合、パターンマッチングが使えなかった点を修正した、ということです。
以下のメソッドのジェネリック型のT
で、パターンマッチングできなかったのを修正したそうです。
private void Run<T>(T value) { switch(value) { case string v: break; } }
C#7.0だとこんなエラーが出ます。内容がすごく親切ですね。
これがC#7.1だと問題ないコードになっています。
おわりに
一応一つ一つ見ていきましたが、小規模な改訂でした。メジャーバージョンで追加された機能に対する追加機能、みたいなものがマイナーバージョンで増えていく感じでしょうかね。
あと、このバージョンのソースサンプルは下記に上げています。ほぼ役に立たないと思いますが、参考までに。