【Unity】Unityで使えるC#6の機能を総まとめ!.Net4.xでモダンなスクリプティングを

Unityで使えるC#6の機能を一通りまとめました。

Unity2018.2

はじめに

この記事ではUnityを使ってC#6の機能をまとめました。
async/awaitはC#5ってのもありますが、何より長くなるため以下の別記事にまとめました。

light11.hatenadiary.com

light11.hatenadiary.com

C#6を使うための準備

UnityでC#6を使うにはまず.Netのバージョンを上げる必要があります。
Player Settings > Other Settings > Configuration > Scripting Runtime Version を .Net 4.xに変更します。

f:id:halya_11:20190304013007p:plain

変更するとUnityの再起動を促されると思うので再起動します。
また、Visual Studioを開いて下記のダイアログが出たら対応する.Netをインストールします。

f:id:halya_11:20190104170730p:plain

これで準備は完了です。
それではC#6の機能を見ていきます。

null条件演算子

Swiftなどでいうところのオプショナルチェインができるようになりました。
nullableな変数に対して下記のように書くことでnullだったらそれ以降の判定が行われなくなり、例外が発生しなくなります(コード見てもらったほうが早いです)。

public struct Example
{
    public int exampleInt;
}

private Example? _example = null;

public void Start()
{
    // 【従来の書き方】_exampleがnullだと例外発生(HasValueでチェックが必要)
    Debug.Log(_example.Value.exampleInt);

    // 【C#6からの機能】この書き方をすると_exampleがnullなら結果もnullになる
    Debug.Log(_example?.exampleInt);
}

System.Actionのnullチェックとかしなくてよくなるのでいい感じです。

private void Example(System.Action callback = null)
{
    callback?.Invoke();
}

ただしこの機能はUnityEngine.Objectとの相性が良くないため使い方に注意が必要です。
これについては以下の記事にまとめていますので、必要に応じて参照してください。

light11.hatenadiary.com

プロパティの初期値

プロパティの初期値を指定できるようになりました。
以前は初期化用のフィールドを用意する必要がありましたが簡潔に書けるようになりました。

// 旧
private int _example = 1;
public int Example { get { return _example; } set { _example = value; } }

// 新
public int Example { get; set; } = 1; // プロパティを初期化できる

メソッドを一行で書く

簡単なメソッドは一行で書けるようになりました。

// 【旧】こんな感じで書く必要があった
private float Pow2(float x)
{
    return x * x;
}

// 【新】一行で書けるようになった
private float Pow2(float x) => x * x;

getterしかないプロパティを一行で書く

前節のメソッドを一行で書くのと同じ機能ですが、
getterしかないプロパティを一行で書けるようになりました。

private int _count;

// プロパティを一行で書く
public string CountStr => _count + "個";

string.Format()してたものを簡潔に

string.Format()で変数と文字列を合成していたような処理を簡潔に書けるようになりました。

var itemName = "りんご";
var itemCount = 5;
    
// 【旧】string.Formatを使う必要があった
Debug.Log(string.Format("{0}が{1}個", itemName, itemCount));

// 【新】$から始めて簡潔に書けるようになった
Debug.Log($"{itemName}が{itemCount}個");

インスタンス名を取得

nameof演算子インスタンスの名前を取れるようになりました。

var exampleInstance = "example";
Debug.Log(nameof(exampleInstance)); // exampleInstance という文字列が取れる

Dictionaryを簡単に初期化

Dictionaryの初期化が簡潔に書けるようになりました。

// 【旧】Dictionaryを作ってからAddしていた
var exampleDic = new Dictionary<string, int>();
exampleDic.Add("りんご", 5);
exampleDic.Add("みかん", 3);

// 【新】こんな感じで初期化できる
var exampleDic = new Dictionary<string, int>()
{
    ["りんご"] = 5,
    ["みかん"] = 3,
};

ちなみにこの機能はインデックス初期化子といい、
Dictionaryだけでなくインデクサでも使用可能です。

他クラスのstaticメソッドを自分のクラスに定義されているかのように使う

using staticを使うと、他クラスに定義されているstaticなメソッドを、
あたかも自分のクラスに定義されているもののように書くことができます。

using UnityEngine;
// UnityEngine.Mathfクラスをusing static
using static UnityEngine.Mathf;

public class Example : MonoBehaviour {

    private void Start()
    {
        // Mathf.Powと書かずPowだけで使えるようになる
        var val = Pow(3, 2);
    }
}

参考

yukuto.net