BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース MicrosoftがC# 8.0をリリース

MicrosoftがC# 8.0をリリース

ブックマーク

原文(投稿日:2019/09/30)へのリンク

Microsoftは先週、.NET Core3.0リリースの一部としてC# 8.0を一般公開することを、.NET Conf 2019同社の開発ブログで同時に発表した。言語機能には新たに、null許容参照型、非同期ストリーム、デフォルトインターフェースメンバ、新しいコードパターンなどが含まれている。これらの新機能はすべて、Visual Studio 2019でサポートされる。

null許容参照型は、新リリースの最も重要な機能のひとつだ。変数がnull値を持ち得るか否か、明示的に表現する構文ルールを使用することによって、null参照例外に関わる状況を防止することがその目的である。このような場合は、変数宣言の型名の最後に?を付加しなければならない(null許容型と同じ)。

string?foo;

型名に?が付加されていなければ、非null許容参照型であると見なされ、コンパイラは非nullルールを適用する — null以外の値で初期化されなければならず、nullを代入することはできない。この動作は次の例のように、変数名の後のnull許容演算子!でオーバーライドすることが可能である(ほとんどの場合、これは推奨されない)。

foo!.Length;

nullを許容するように警告を設定するか、あるいはnullを許容するアノテーションを指定することで、null許容コンテキスト(nullable context)を使用することもできる。null許容コンテキストはプロジェクトレベルか、あるいはソースコードファイル内の#nullableおよび#pragma warningプリプロセスディレクティブを使用して指定することができる。また、型はそれぞれ、4つのnull許容度(nullability) — Oblivioiusnonnullablenullableunknownのいずれかを持つことができる。null許容度の違いは、異なるコンパイラの挙動を引き起こす。null許容参照型の完全な使用はこちらに記載されている。

もうひとつの重要な機能は、非同期ストリームの導入である。その目的は、イテレータと非同期を両立するメソッドのサポートを導入することだ。このようなメソッドは、(IoTデバイスやクラウドサービスなどによる)継続的な結果ストリームをコンシュームないしプロデュースする必要のあるシナリオで使用することができる。

非同期ストリームはIAsyncEnumerable<T>およびIAsyncEnumerator<T>インターフェースを通じて実装され、(C# 5.0で最初に導入された)async/await機能と同時に使用することができる。非同期ストリームを返すメソッドは、asyncモディファイアで宣言した上で、新しいインターフェースのいずれかを戻り型として持つ必要がある。また、非同期ストリーム内の連続的な要素を返すために、yield return文を含まなくてはならない。

 

以下の例は、Microsoftの公式ドキュメントに含まれているもので、100ミリ秒のウェイトを挟みながら、0から19の値を返すメソッドを実装している。

public static async System.Collections.Generic.IAsyncEnumerable<int> GenerateSequence()
{
    for (int i = 0; i < 20; i++)
    {
        await Task.Delay(100);
        yield return i;
    }
}

非同期ストリームに関する詳細は、公式言語仕様に記載されている。

デフォルトインターフェースメンバは、インターフェースにメンバを追加して、それらメンバの実装を提供する(つまり、インターフェースの具体的な実装を持ったメソッドを可能にする)機能である。APIの開発者が、既存インターフェースの過去バージョンとの互換性を損なわずにソッドを追加できるようにすることで、柔軟性を向上しようというものだ。機能的には、Javaのデフォルトメソッドに近い。

C# 8.0にはさらに、Recursive Pattern Matchingusingステートメントに関連するパターンの、2つの新しいパターンが追加されている。Recursive Patternは、簡単に言えば、他のパターン — 例えば下例(Microsoftの公式ドキュメントから引用)にように — を含めることができるものだ。

IEnumerable<string> GetEnrollees()
{
    foreach (var p in People)
    {
        if (p is Student { Graduated: false, Name: string name }) yield return name;
    }
}

Student { Graduated: false, Name: string name }パターンは、PersonStudentであることをチェックした上で、まだ登録されていれば、そのGraduatedプロパティに定数パターンfalseを、(nullでなければ)名称を取得するNameプロパティにstring nameパターンを、それぞれ適用する。従って、pStudentで、卒業していなくて、非nullの名前を持っていれば、その名前を返す。

usingステートメントに関する新しいパターンは、ローカル関数宣言に追加することにより、usingローカルのライフタイムが、それが宣言されているスコープの終了まで延長される、というものだ。複数のusingローカルが存在する場合は、宣言とは反対の順序で破棄される。

{
    using var foo1 = new FileStream("...");
    using var foo2 = new FileStream("...");
    ...
    // Dispose foo2
    // Dispose foo1
}

usingステートメントに関するもうひとつのの新機能は、Disposable Patternの概念、すなわち、アクセス可能なDisposeインスタンスメソッドを持っった型だ。このパターンに従う型は、IDisposableを実装しなくてもusingステートメントで使用することができる。

class Bar
{
    public void Dispose() { ... }
}

using (var foo = new Bar())
{
    // statements
}

C# 8.0で追加された他の機能としては、switchステートメント構文の変更やtarget-typed new式がある。これらにより、型が既知のコンテキストで新たにオブジェクトを生成する場合、型宣言を省略することが可能になる。

Vector2[] vectors = { new (1, 1), new (2, -1) };

新機能の概要はこちらで、C# 8.0の完全な仕様提案はこちらで確認できる。また、新機能の紹介を中心に行われた.NET Conf 2019での技術セッションを、YouTube(こちらこちら)で見ることができる。C# 8.0は、Visual Studio 2019の全バージョンに含まれている。

この記事に星をつける

おすすめ度
スタイル

BT