はじめに
Unity 2020.2a から C# 8.0 の機能がいくつか使用できるようになりました
マイクロソフトの公式ページで C# 8.0 の新機能が紹介されておりますが、
この新機能の中から、現時点で使用できることが確認できた機能と
使用できなかった機能をいくつか紹介していきます
検証環境
- Unity 2020.2.0a21
- Visual Studio 2019
目次
使えた機能
読み取り専用メンバー
using UnityEngine; public class Example : MonoBehaviour { private void Awake() { var character = new Character(); Debug.Log(character.Name); Debug.Log(character.GetName()); } } public struct Character { // ★ public readonly string Name => "ピカチュウ"; // ★ public readonly string GetName() => "ピカチュウ"; }
switch 式
using System; using UnityEngine; public class Example : MonoBehaviour { private void Awake() { Debug.Log(GetName(3)); // フシギバナ } private string GetName(int i) { // ★ return i switch { 1 => "フシギダネ", 2 => "フシギソウ", 3 => "フシギバナ", _ => throw new ArgumentException(), }; } }
プロパティパターン
using UnityEngine; public class Example : MonoBehaviour { private void Awake() { Debug.Log(GetName(Vector2Int.up)); // 上 } private string GetName(Vector2Int vec) { // ★ return vec switch { { x: -1, y: 0 } => "左", { x: 1, y: 0 } => "右", { x: 0, y: 1 } => "上", { x: 0, y: -1 } => "下", }; } }
タプルパターン
using UnityEngine; public class Example : MonoBehaviour { private void Awake() { Debug.Log(GetName(0, 1)); // 上 } private string GetName(int x, int y) { // ★ return (x, y) switch { { x: -1, y: 0 } => "左", { x: 1, y: 0 } => "右", { x: 0, y: 1 } => "上", { x: 0, y: -1 } => "下", }; } }
位置指定パターン
using UnityEngine; public static class Vector2IntExt { public static void Deconstruct ( this Vector2Int self, out float x, out float y ) { x = self.x; y = self.y; } } public class Example : MonoBehaviour { private void Awake() { Debug.Log(GetName(Vector2Int.up)); // 上 } private string GetName(Vector2Int vec) { // ★ return vec switch { var (x, y) when x < 0 && y == 0 => "左", var (x, y) when 0 < x && y == 0 => "右", var (x, y) when x == 0 && 0 < y => "上", var (x, y) when x == 0 && y < 0 => "下", }; } }
using 宣言
using System; using UnityEngine; public class Example : MonoBehaviour { private void Awake() { // ★ using var character = new Character(); Debug.Log("ピカチュウ"); // Awake 関数を抜ける時に「カイリュー」と出力される } } public class Character : IDisposable { public void Dispose() { Debug.Log("カイリュー"); } }
静的ローカル関数
using System; using UnityEngine; public class Example : MonoBehaviour { private void Awake() { // ★ static string GetName() => "ピカチュウ"; Debug.Log(GetName()); } }
null 許容参照型
using UnityEngine; // ★ #nullable enable public class Example : MonoBehaviour { // ★ string? GetName() => null; private void Awake() { Debug.Log(GetName()); } }
null 合体割り当て
using UnityEngine; public class Example : MonoBehaviour { private void Awake() { string name = null; // ★ Debug.Log( name ??= "ピカチュウ" ); // ピカチュウ Debug.Log( name ??= "カイリュー" ); // ピカチュウ } }
verbatim 補間文字列の拡張
using UnityEngine; public class Example : MonoBehaviour { private void Awake() { var dir = "tmp"; Debug.Log( $@"C:\{dir}" ); // C# 7.3 以前も使用可 Debug.Log( @$"C:\{dir}" ); // C# 8 以降から使用可 } }
使えなかった機能
既定のインターフェイスメソッド
error CS8701: Target runtime doesn't support default interface implementation.
- 既定のインターフェイスメソッド定義したところ
上記のコンパイルエラーが発生して使用できなかった
非同期ストリーム
- .NET Standard 2.1 がサポートされていない関係で
System.Collections.Generic.IAsyncEnumerable が見つからず使用できなかった
インデックスと範囲
- .NET Standard 2.1 がサポートされていない関係で
System.Index と System.Range が見つからず使用できなかった
補足
Visual Studio 2019 が必要
Visual Studio 2017 は基本的には C# 8.0 に対応していないため
Unity 2020.2a + Visual Studio で C# 8.0 を使用したい場合は
Visual Studio 2019 をインストールする必要があります
一応、下記のページを見る限り Visual Studio 2017 で
C# 8.0 を使用する方法もあるようですが未検証
https://stackoverflow.com/questions/54701377/how-can-i-use-c-sharp-8-with-visual-studio-2017
.csproj の言語バージョンに 8.0 を指定するエディタ拡張が必要
少なくとも Unity 2020.2.0a21 で .csproj を生成すると
生成された .csproj の言語バージョンが 7.3 になっているため、
C# 8.0 の機能を使用してコーディングすると
Visual Studio 側でエラーが表示されてしまいます
上記ページで公開されているエディタ拡張を Unity プロジェクトに追加すると
生成される .csproj の言語バージョンが 8.0 に置き換わるため、
Visual Studio 上で C# 8.0 の機能を使用してもエラーが表示されないようになります