1分で分かる C# 7.1 の新機能

[What's new in C# 7.1](https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-7-1)、[Welcome to C# 7.1](https://blogs.msdn.microsoft.com/dotnet/2017/10/31/welcome-to-c-7-1/) をベースに、C# 7.0 と比較してコードがどう変わるのかを記載しています。


## 1. [`async` `Main` メソッド (`async` `Main` method)](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/main-and-command-args/index)
```csharp:old
static void Main() {
    MainAsync().GetAwaiter().GetResult();
}

static async Task MainAsync() {
    ... // await code
}
```
<div>:arrow_down:</div>
```csharp:new!
static async Task Main() {
    ... // await code
}
```
※ `Main` メソッドに `async` を修飾できるのは、戻り値の型が `Task` or `Task<int>` の場合のみです。`async void Main` はコンパイルエラー CS5001 となります。[詳細はこちら](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.1/async-main.md#detailed-design)。


## 2. [`default` リテラル式 (`default` literal expressions)](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/statements-expressions-operators/default-value-expressions#default-literal-and-type-inference)
```csharp:old
Func<string, bool> whereClause = default(Func<string, bool>);
```
<div>:arrow_down:</div>
```csharp:new!
Func<string, bool> whereClause = default;
```


## 3. [推論されたタプル要素の名前 (Inferred tuple element names)](https://docs.microsoft.com/ja-jp/dotnet/csharp/tuples#tuple-projection-initializers)
別名、_タプル プロジェクション初期化子 (Tuple projection initializers)_。

```csharp:old
int width, height;
...
var rect = (width:width, height:height);
Console.WriteLine($"{rect.width}x{rect.height}");
```
<div>:arrow_down:</div>
```csharp:new!
int width, height;
...
var rect = (width, height);
Console.WriteLine($"{rect.width}x{rect.height}");
```


## 4. [pattern-matching with generics](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.1/generics-pattern-match.md)
C# 7.0 パターンマッチングの bug-fix レベルの変更。
以前は[オープン型](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/language-specification/types#open-and-closed-types)の式（変数）のマッチングが行えませんでしたが、C# 7.1 で対応されました。

```csharp:old
public interface IShape {}
public struct Rectangle : IShape {}

public void Draw<T>(T shape) where T: IShape {
    // キャストが必要。外すとコンパイルエラー。
    if ((IShape)shape is Rectangle rect1) {
        ...
    }

    // キャストが必要。外すとコンパイルエラー。
    switch ((IShape)shape) {
        case Rectangle rect2:
            ...
            break;
    }
}
```
<div>:arrow_down:</div>
```csharp:new!
public interface IShape {}
public struct Rectangle : IShape {}

public void Draw<T>(T shape) where T: IShape {
    if (shape is Rectangle rect1) {
        ...
    }

    switch (shape) {
        case Rectangle rect2:
            ...
            break;
    }
}
```

## For more information
- [What's new in C# 7.1 | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-7-1)
- [Welcome to C# 7.1 | .NET Blog](https://blogs.msdn.microsoft.com/dotnet/2017/10/31/welcome-to-c-7-1/)
- [csharplang/Language-Version-History.md at master · dotnet/csharplang > C# 7.1 (Visual Studio 2017 version 15.3)](https://github.com/dotnet/csharplang/blob/master/Language-Version-History.md#c-71-visual-studio-2017-version-153)


## Related Posts
- [10分で分かる C# 7.0 の新機能](https://qiita.com/inasync/items/bba3e4b9d370b7e5589e)
- [3分で分かる C# 6 の新機能](https://qiita.com/inasync/items/c653d7a952a873fef8b0)