C# 8/9の新機能は、コンパイラーさえ新しければ(例えばVisual Studio 2019を使えば)、ターゲット環境が.NET Frameworkでも使用できます。
(なお推奨されない使い方です。)
ただし、Nugetパッケージ参照が必要だったり、Shimコードが必要だったりします。
プロジェクトファイルの編集
.NET Frameworkのデフォルト言語バージョンは7.3なので、<PropertyGroup>タグの中に
<LangVersion>9.0</LangVersion>
を足しましょう。
古いcsprojファイル形式のままでも、<LangVersion>を足すだけで大丈夫です。
C# 8.0新機能
| C# 8.0 | Note | |
|---|---|---|
| 読み取り専用メンバー | ✔ | |
| 既定のインターフェイス メソッド | ✖ | |
| パターン マッチングの拡張機能 | ✔ | |
| using 宣言 | ✔ | |
| 静的ローカル関数 | ✔ | |
| Dispose可能な ref 構造体 | ✔ | |
| Null 許容参照型 | ⚠ | コードには付けられるが、BCLが対応していない |
| 非同期ストリーム | ⚠ | サードパーティーのパッケージが必要 |
| 非同期のDisposable | ⚠ | サードパーティーのパッケージが必要 |
| インデックスと範囲 | ⚠ | サードパーティーのパッケージが必要1 |
| null 合体割り当て | ✔ | |
| 構築されたアンマネージド型 | ✔ | |
| 入れ子になった式の stackalloc | ✔ | |
| 逐次補間文字列の拡張 | ✔ |
C# 9.0新機能
| C# 9.0 | Note | |
|---|---|---|
| レコード | ⚠ |
IsExternalInitの定義が必要 |
| init 専用セッター | ⚠ |
IsExternalInitの定義が必要 |
| 最上位レベルのステートメント | ✔ | |
| パターン マッチングの拡張機能 | ✔ | |
| ネイティブ サイズの整数 | ✔ | |
| 関数ポインター | ⚠ | managedポインターは可。unmanagedポインターは不可。 |
| localsinit フラグの出力を抑制する | ⚠ |
SkipLocalsInit属性の定義が必要 |
| ターゲット型の新しい式 | ✔ | |
| 静的な匿名関数 | ✔ | |
| ターゲットにより型指定された条件式 | ✔ | |
| 共変の戻り値の型 | ✖ | |
| foreach ループの拡張機能 GetEnueeeemerator サポート | ✔ | |
| ラムダ ディスカード パラメーター | ✔ | |
| ローカル関数の属性 | ✔ | |
| モジュールの初期化子 | ⚠ |
ModuleInitializer属性の定義が必要 |
| 部分メソッドの新機能 | ✔ |
IsExternalInitクラス
namespace System.Runtime.CompilerServices
{
internal static class IsExternalInit
{
}
}
SkipLocalsInit属性
namespace System.Runtime.CompilerServices
{
[System.AttributeUsage(System.AttributeTargets.Class |
System.AttributeTargets.Constructor |
System.AttributeTargets.Event |
System.AttributeTargets.Interface |
System.AttributeTargets.Method |
System.AttributeTargets.Module |
System.AttributeTargets.Property |
System.AttributeTargets.Struct, Inherited = false)]
internal sealed class SkipLocalsInitAttribute : System.Attribute
{
}
}
ModuleInitializer属性
namespace System.Runtime.CompilerServices
{
[System.AttributeUsage(AttributeTargets.Method, Inherited = false)]
internal sealed class ModuleInitializerAttribute : System.Attribute
{
}
}
-
例えばIndexRange ↩