次の方法で共有


分解式 - タプルまたはその他のユーザー定義型のプロパティやフィールドを抽出する

分解式は、オブジェクトのインスタンスのデータ フィールドを抽出します。 個々のデータ要素は、次の例に示すように、それぞれ個別の変数に書き込まれます。

var tuple = (X: 1, Y: 2);
var (x, y) = tuple;

Console.WriteLine(x); // output: 1
Console.WriteLine(y); // output: 2

上記のコード スニペットは、2 つの整数値 X を持つYを作成します。 2 番目のステートメントは、タプルを 分解 し、タプル要素を個別の変数 x および yに格納します。

C# 言語リファレンスには、C# 言語の最新リリース バージョンが記載されています。 また、今後の言語リリースのパブリック プレビューの機能に関する初期ドキュメントも含まれています。

このドキュメントでは、言語の最後の 3 つのバージョンまたは現在のパブリック プレビューで最初に導入された機能を特定します。

ヒント

C# で機能が初めて導入された時期を確認するには、 C# 言語バージョン履歴に関する記事を参照してください。

タプルの分解

すべてのタプル型は、分解式をサポートしています。 タプルの分解では、タプルのすべての要素を抽出します。 タプル要素の一部のみを使用する場合は、次の例に示すように、未使用のタプル メンバーに 対して破棄 を使用します。

var tuple2 = (X: 0, Y: 1, Label: "The origin");
var (x2, _, _) = tuple2;

先ほどの例では、Ylabel のメンバーは破棄されます。 同じ分解式で複数の破棄を指定できます。 タプルのすべてのメンバーについて、破棄を使用できます。 次の例は、構文的には正しいですが、実用的ではありません。

var (_, _, _) = tuple2;

レコードの分解

プライマリ コンストラクターを持つレコード型は、位置指定パラメーターの分解をサポートします。 コンパイラは、プライマリ コンストラクターの位置指定パラメーターから自動的に生成されたプロパティの値を抽出する Deconstruct メソッドを自動的に生成します。 ただし、コンパイラが自動的に生成する Deconstruct メソッドは、レコード型内で明示的にプロパティとして宣言されたものは抽出しません。

次のコードに示す record は、SquareFeetAddress という 2 つの位置指定プロパティと、もう 1 つの RealtorNotes というプロパティを宣言しています。

public record House(int SquareFeet, string Address)
{
    public required string RealtorNotes { get; set; }
}

House オブジェクトを分解するとき、次の例に示すように、位置指定プロパティのみが分解対象となります。

var house = new House(1000, "123 Coder St.")
{
    RealtorNotes = """
    This is a great starter home, with a separate room that's a great home office setup.
    """
};

var (squareFeet, address) = house;
Console.WriteLine(squareFeet); // output: 1000
Console.WriteLine(address); // output: 123 Coder St.
Console.WriteLine(house.RealtorNotes);

この動作を利用して、コンパイラが生成する Deconstruct メソッドに、レコード型のどのプロパティを含めるかを指定できます。

Deconstruct メソッドを宣言する

宣言するあらゆるクラス、構造体、またはインターフェイスに分解機能を実装できます。 型で 1 つ以上の Deconstruct メソッドを宣言するか、その型の拡張として宣言します。 分解式は void Deconstruct(out var p1, ..., out var pn) メソッドを呼び出します。 Deconstruct メソッドはインスタンス メソッドまたは拡張メソッドのいずれかになります。 Deconstruct メソッドの各パラメーターの型は、分解式の対応する引数の型と一致する必要があります。 分解式では、各引数の値が out メソッドの対応する Deconstruct パラメーターの値に代入されます。 分解式に一致する Deconstruct メソッドが複数ある場合、コンパイラはあいまいさに関するエラーを報告します。

次のコードでは、2 つの Point3D メソッドを定義した Deconstruct 構造体を宣言しています。

public struct Point3D
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Z { get; set; }

    public void Deconstruct(out int x, out int y, out int z)
    {
        x = X;
        y = Y;
        z = Z;
    }

    public void Deconstruct(out int x, out int y)
    {
        x = X;
        y = Y;
    }
}

最初のメソッドは 3 つの軸の値 XYZ を抽出するものです。 2 番目のメソッドは平面値 XY のみを分解するものです。 最初のメソッドの引数の数 (arity) は 3 で、2 番目のメソッドの引数の数は 2 です。

前のセクションでは、プライマリ コンストラクターを持つ Deconstruct 型に対して、コンパイラによって生成された record メソッドについて説明しました。 レコード型では、さらに多くの Deconstruct メソッドを宣言できます。 これらのメソッドでは、他のプロパティを追加したり、既定のプロパティの一部を削除したり、またはその両方を行うことができます。 また、コンパイラが自動的に生成するシグネチャと一致する Deconstruct を宣言することもできます。 そのような Deconstruct メソッドを宣言した場合、コンパイラはメソッドを自動的に生成しません。

コンパイラが分解式に対して一意の Deconstruct メソッドを特定できる限り、複数の Deconstruct メソッドを定義できます。 通常、同じ型に複数の Deconstruct メソッドを定義する場合は、パラメーターの数を変えます。 また、パラメーターの型を変えることで、複数の Deconstruct メソッドを定義することもできます。 ただし、Deconstruct メソッドを多用すると、コンパイラが適切なメソッドを特定できなくなり、予期しない結果を招く可能性があります。

C# 言語仕様

詳細については、C# 標準の分解のセクションを参照してください。

関連項目