【C#】独自の型にDeconstructメソッドで分解宣言・分解代入できるようにする

C#で独自の型にDeconstructメソッドを追加して分解宣言・分解代入できるようにする方法です。

Unity2020.2.3(動作確認はUnityで行っています)

分解宣言・分解代入?

C#7でTupleが追加されました。
Tupleを使うと以下のように複数の値を持つ型を定義できます。

// タプル型の変数宣言
(int userId, string userName) taro = (1, "太郎");

// タプルにアクセス
taro.userId;
taro.userName;
タプル型の分解宣言

上記ではタプル型の変数として宣言していますが、
以下のように書くとタプルの中身を分解しつつ変数を宣言できます。

// タプルを分解しつつ二つの変数を宣言
(int userId, string userName) = (1, "太郎");

// アクセス
userId;
userName;

これを分解宣言といいます。
以下のように型推論を効かせることも可能です。

(var userId, var userName) = (1, "太郎");
var (userId, userName) = (1, "太郎");
分解代入

タプルを分解しつつ代入するのも宣言と同じ要領で行えます。

int userId = -1;
string userName = string.Empty;

// 代入
(userId, userName) = (1, "太郎");

独自の型にDeconstructメソッドで分解宣言・分解代入できるようにする

さてこの分解宣言や分解代入ですが、Tuple型に限った機能ではありません。
以下のようにDeconstructメソッドを定義することで独自の型を分解することができるようになります。

public readonly struct Position
{
    public readonly int X;
    public readonly int Y;

    public Position(int x, int y)
    {
        X = x;
        Y = y;
    }

    // Deconstructメソッドで分解できるように
    public void Deconstruct(out int x, out int y)
    {
        (x, y) = (X, Y);
    }
}

この構造体を以下のように使うと分解できることが確認できます。

var position = new Position(1, 2);
var (x, y) = position;

Debug.Log($"{x}, {y}");

関連

light11.hatenadiary.com