なんか、Visual Studio 2019 Preview 2が出てますね。

リリースノート上は、.NET 関連はまた「リファクタリング機能が増えたよ」みたいな感じのアナウンス。

あとは、自分が手元で確認してみた感じ、Preview 1の頃から3つほど C# 8.0 の実装が増えてました。

  • 再帰パターン
  • using の改善
  • 静的ローカル関数

動作確認で使ったコード: Demo/2019/Csharp80/Preview2

再帰パターン

これは Preview 1 で入ると思ってたのに入らなかったというくらいなので、 前に、sharplab.ioで動作確認しながら書いた以下の2つのブログほぼそのまま。

一応、0引数・1引数での Deconstruct ができるようになったりしているみたいです。

using System;
 
struct X
{
    public void Deconstruct() { }
    public void Deconstruct(out int x) => x = 0;
    public void Deconstruct(out int x, out int y) => (x, y) = (0, 0);
}
 
class Program
{
    static void Main()
    {
        var x = new X();
        Console.WriteLine(x is ());      // 0引数
        Console.WriteLine(x is var (_)); // 1引数のだけは、() 式とかキャストとかとの弁別のために var 必須
        Console.WriteLine(x is (_, _));  // 2引数
    }
}

using の改善

2つほど。

  • ref struct に限り、IDisposable インターフェイスを実装していなくても、パターン ベースでDisposeメソッドを呼んでくれるようになった
  • using var で、ローカル変数のスコープに紐づいたリソースの破棄(Dispose メソッド呼び出し)ができるようになった

はい、残念なお知らせ。パターン ベースでのDispose呼び出しがref struct限定になりました。 そうしないと破壊的変更を起こす可能性があってやむなく限定したそうです。

using System;
 
// インターフェイスなし、ref なし
struct A { public void Dispose() { } }
 
// インターフェイスあり
struct B : IDisposable { public void Dispose() { } }
 
// ref あり
ref struct C { public void Dispose() { } }
 
class Program
{
    static void Main()
    {
        using var a = new A(); // ダメ
        using var b = new B(); // 元々 OK
        using var c = new C(); // C# 8.0 で OK に
    }
}

静的ローカル関数

ローカル関数に static 修飾を付けることで、ローカル変数のキャプチャをしないということを明示できるようになります。

// ローカル関数に static を付けると、ローカル変数をキャプチャできなくなる。
static int a(int x) => 2 * x;
 
// 以下のコードは2行目の n のところでエラーに。
int n = 0;
static int b(int x) => n * x;

Preview 1 からのその他の修正

Async streamsはいまだに動きません… これは、たぶん、 .NET Core 3.0 の方の Preview 2が来れば解消される気がします。

あと、null許容参照型は、以下のような変更が掛かってそう

  • プロジェクト全体に対して null 解析をオンにするためのオプションが以下のように変更されてそう
    • 旧: <NullableReferenceTypes>true</NullableReferenceTypes>
    • 新: <NullableContextOptions>Enable</NullableContextOptions>
  • 解析が走るタイミングが変わっていそう(たぶん)
    • 旧: 常時
    • 新: ファイルを開いているとき