目次
はじめに
Unity 2020.2 で C# 8.0 の機能がサポートされました。
本記事ではUnity 2020.2 から使える C# 8.0 の機能を紹介します。
C# 8.0 の機能
読み取り専用メンバー
構造体のメンバーに readonly
修飾子が適用可能になり、書き換え不可を保証できるようになりました。
public struct Address
{
public float X { get; set; }
public float Y { get; set; }
// メンバーに readonly 修飾子を適用可能に
public readonly override string ToString() => $"X: {X}, Y: {Y}";
}
switch 式
switch を式として記述でき、より簡潔で伝わりやすい構文が書けるようになりました。
public enum Fruit
{
Apple,
Banana,
Melon,
}
public static Color ToColor(Fruit fruit) =>
fruit switch
{
Fruit.Apple => Color.red,
Fruit.Banana => Color.yellow,
Fruit.Melon => Color.green,
_ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(fruit)),
};
}
switch 構文の改良点
- 変数を
switch
キーワードの前に記述 case
と:
を=>
に置き換え可能default
は_
に書き換え可能
プロパティ パターン
switch 文からプロパティにアクセスして式を記述できるようになりました。プロパティ名と:
の後に条件にマッチさせたい値を記載します。複数のプロパティを扱う場合は ,
で区切ります。
以下は先程記載した Address
クラスを参考に、プロパティのX
とY
を使ったパターン例です。
static int MatchNum(Address address) =>
address switch
{
{X: 1, Y: 1} => 1,
{X: 2, Y: 2} => 2,
{X: _, Y: 3} => 3,
_ => -1,
};
}
タプル パターン
Switch 式でタプルが使用可能になりました。
public static string AttributeResult(string first, string second)
=> (first, second) switch
{
("Fire", "Water") => "Water wins.",
("Fire", "Grass") => "Fire wins.",
("Water", "Fire") => "Water wins.",
("Water", "Grass") => "Grass wins.",
("Grass", "Fire") => "Fire wins.",
("Grass", "Water") => "Grass wins.",
(_, _) => "Invalid"
};
}
using 宣言
変数宣言時に using を付けられるようになりました。これは using ステートメントと同じ処理が行われます。
static void Main()
{
// 変数宣言前の using で、スコープを抜ける時に Dispose が呼ばれる
using var fs = new FileStream("sample.txt", FileMode.Open);
Console.WriteLine(fs.Length);
// ここで Dispose が呼ばれる
}
C# 7.3 以前の using ステートメントの書き方
static void Main()
{
using (var fs = new FileStream("sample.txt", FileMode.Open))
{
Console.WriteLine(fs.Length);
}
}
静的ローカル関数
ローカル関数に static
修飾子を付けられるようになりました。これを静的ローカル関数と呼び、ローカル関数で外部変数が参照されない設定が可能になります。
void Test(int num)
{
// 外部の変数である num を使用可能
int Add(int x) => num + x;
// static を付けると外部変数の num が参照不可になる
// この場合コンパイルエラーが発生
static int Minus(int x) => num - x;
}
null 許容参照型
参照型の変数はすべて「null 非許容参照型」と見なされますが、変数宣言時に型名に?
と書くことで null が許容であることを示す「null 許容参照型」として扱えるようになりました。
これはディレクティブに#nullable enable
を記載することで有効になります。
// null 許容参照型 を有効にする
#nullable enable
class Program
{
string str1 = string.Empty;
string str2 = null;
string? str3 = null;
void TextLength()
{
// str2 は null の可能性があるが警告エラーなし
int textLength1 = str1.Length + str2.Length;
// str3 に null の可能性を示す警告エラーが出る
int textLength2 = str1.Length + str3.Length; // warning CS8602: Dereference of a possibly null reference.
}
}
参照型を null 許容参照型 として宣言することで、コンパイラにてフロー解析が行われます。これにより意図しない null エラーを事前に避けることができます。
null 合体割り当て
null 合体割り当て演算子 ??=
が使えるようになりました。
左側のオペランドが null の場合に??=
を使用して右側のオペランドの値を左側に割り当てられます。
static void Test(string str = null)
{
str ??= "sample text";
Console.WriteLine(str);
}
verbatim 補間文字列の拡張
C# 7.3 以前では、文字列リテラルの前に$@
と付けることで複数行の文字列補間が可能でした。C# 8.0 から @$
、つまり表記が逆でも文字列補間が認められるようになりました。
// C# 7.3 以前から使用可
var sample1 = $@"
sample
test";
// C# 8.0 から使用可
var sample2 = @$"
sample
test";
}
参考資料
参考 C# 8.0 の新機能++C++; // 未確認飛行 C
参考 【Unity】Unity 2020.2a から C# 8.0 の機能がいくつか使用できるようになったコガネブログ