62K Views
March 17, 23
スライド概要
最新のC#を使おう!
このスライドについて • お使いのC#プロジェクトで最新のC#機能を使う方法を解 説します • Unityに関する情報も少し解説します • 著者:ナムアニクラウド(NumAniCloud) • ゲーム開発に興味があります • 抽象的な構造に興味があります Twitterアイコン
はじめに: Unityを使っているひと? Unity Editorから(asmdefなどで)生成されるプロジェクトを使っているひとは …… そのC#バージョンがUnityで使える限りの最新です
最新のC#の使い方
最新のC#バージョンは? 🥳 C# 11.0 🥳
どんな環境でもC# 11.0を使える? 😭 いいえ 😭
なぜ最新のC#を使えないのか • コンパイラのバージョンが古い場合 • ランタイムのバージョンが古い場合 • ランタイムのバージョンは十分だがプロジェクト設定で 無効にしている場合 • Unityでは使えない場合
なぜ最新のC#を使えないのか • コンパイラのバージョンが古い場合 • ランタイムのバージョンが古い場合 • ランタイムのバージョンは十分だがプロジェクト設定で 無効にしている場合 これって今すぐ解決できるよね • Unityでは使えない場合
C#11を使えるようにしてみよう コンパイラがC#11に対応していると仮定します Project.csproj (変更前) <Project Sdk=“Microsoft.NET.Sdk”> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <LangVersion>9<LangVersion> </PropertyGroup> この設定があると、 </Project> C#9.0までしか使えない
C#11を使えるようにしてみよう コンパイラがC#11に対応していると仮定します Project.csproj (変更後) <Project Sdk=“Microsoft.NET.Sdk”> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <LangVersion>11<LangVersion> </PropertyGroup> この設定なら、 </Project> C#11.0まで使える
このプロジェクト設定なら必ずC#11.0を使える? 😭 いいえ 😭
なぜ最新のC#を使えないのか • コンパイラのバージョンが古い場合 統合開発環境ごとにコンパイラの • ランタイムのバージョンが古い場合 バージョンが違うことがあるので注意 • ランタイムのバージョンは十分だがプロジェクト設定で 無効にしている場合 • Unityでは使えない場合
UnityバージョンとC#バージョン Unity Editor上でのビルドに使われるコンパイラは、いつも最新とは限らない Unityバージョン C#バージョン Unity 2019.1 ~ C# 7.3 Unity 2020.2 ~ C# 8.0 Unity 2021.2 ~ Unity 2023.1 C# 9.0 はやくC# 10.0 使いたいなあ
最新コンパイラなら最新C#の機能を全部使える? 😭 いいえ 😭
なぜ最新のC#を使えないのか • コンパイラのバージョンが古い場合 • ランタイムのバージョンが古い場合 • ランタイムのバージョンは十分だがプロジェクト設定で 無効にしている場合 • Unityでは使えない場合
ランタイムのバージョンを新しくしてみよう C#バージョンが使えないのではなく、特定のC#機能が使えないパターン Project.csproj (変更前) <Project Sdk=“Microsoft.NET.Sdk”> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <LangVersion>11<LangVersion> </PropertyGroup> </Project> この設定では例えば、 requiredプロパティが使えない
ランタイムのバージョンを新しくしてみよう C#バージョンが使えないのではなく、特定のC#機能が使えないパターン Project.csproj (変更前) <Project Sdk=“Microsoft.NET.Sdk”> <PropertyGroup> <TargetFramework>net7.0</TargetFramework> <LangVersion>11<LangVersion> </PropertyGroup> </Project> .NET 7 では、 requiredプロパティがサポートされる
ランタイムでサポートされていないパターン .NET のアプリは以下のようなランタイムをに依存して動作します: • .NET Framework • .NET Standard 2.1 • .NET 5.0 • .NET 6.0 • .NET 7.0
ランタイムでサポートされていないパターン .NET のアプリは以下のようなランタイムをに依存して動作します: • .NET Framework • .NET Standard 2.1 • .NET 5.0 • .NET 6.0 • .NET 7.0 Unity 2022で使うランタイムはこれ
動かすのに工夫が要る機能 ランタイム バージョン このランタイムが必須な機能 .NET Standard 2.1 .NET 5 init-onlyプロパティ .NET 6 .NET 7 requiredプロパティ これらは古いランタイムで使う方法があります(後述)
どうしても動かせない機能 ランタイム バージョン このランタイムが必須な機能 .NET Standard 2.1 インターフェースのデフォルト実装 .NET 5 メソッドの共変戻り値 .NET 6 .NET 7 refフィールド, Numeric IntPtr, インターフェースの静的抽象メンバー 重要な機能だけかいつまみました
なぜ最新のC#を使えないのか • コンパイラのバージョンが古い場合 • ランタイムのバージョンが古い場合 • ランタイムのバージョンは十分だがプロジェクト設定で 無効にしている場合 • Unityでは使えない場合
Unityでサポートされない機能 • モジュール初期化子 • ローカル変数の0初期化抑止 このあたりはサポートされなくても仕方ない感じはする
古いランタイムでもできる事
init-onlyプロパティ 初期化子からに限ってプロパティの値をsetできるようにする機能 通常、 .NET 5 が必要な機能 var hoge = new Hoge { X = 12 }; // 初期化子が使える hoge.X = 16; // setは変わらず禁止のまま // setアクセサの代わりに、initと書く public class Hoge { public int X { get; init; } }
init-onlyアクセサ 以下のようなクラスをプロジェクトに追加しておくと、 .NET 5 ランタイム を使っていなくても init-only プロパティを使えます init-onlyが使えるようになると、record型も使えます namespace System.Runtime.CompilerService { // internal なクラスとして定義すると、 // 別々のプロジェクトで重複して定義しても大丈夫なので便利 internal class IsExternalInit { } }
requiredプロパティ initアクセサのあるプロパティにつけると、初期化子で初期化することを強 制できる 通常、 .NET 7 が必要な機能 public class Hoge { public required int X { get; init; } // こういうコンストラクタはもう書かなくてよくなる public Hoge(int x) { X = x; } }
requiredプロパティ .NET 7 ランタイムがないときは、以下のクラスが必要 namespace System.Runtime.CompilerService { internal class RequiredMemberAttribute : Attribute { } }
requiredプロパティ 以下のようなクラスも必要 namespace System.Runtime.CompilerService { internal class CompilerFeatureRequiredAttribute : Attribute { public CompilerFeatureRequiredAttribute(string featureName) { } } }
補足: C#バージョン指定
default & preview コンパイラのバージョンに合わせて言語バージョンを選んでくれる機能が あります Project.csproj (変更前) <Project Sdk=“Microsoft.NET.Sdk”> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <LangVersion>default<LangVersion> </PropertyGroup> Visual Studio 17.4.3 だと </Project> C# 10.0 が選ばれる
default & preview コンパイラのバージョンに合わせて言語バージョンを選んでくれる機能が あります Project.csproj (変更前) <Project Sdk=“Microsoft.NET.Sdk”> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <LangVersion>preview<LangVersion> </PropertyGroup> Visual Studio 17.4.3 だと </Project> C# 11.0 が選ばれる
まとめ
まとめ C# の最新機能がいつでも使えるとは限らない • プロジェクト設定にて適切な設定をする必要がある • コンパイラが対応しているC#バージョンまでしか使えない • ランタイムが古いと、コンパイラが対応しているC#バージョンの機能で あっても使えない機能があったりする • 工夫すると使えるようになる場合と、どう頑張っても使えない場合がある • Unityで対応していないC#機能もある