次の方法で共有


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

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

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

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

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

タプルの分解

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

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

前の例では、Y メンバーと label メンバーは破棄されます。 同じ分解式で複数の破棄を指定できます。 タプルのすべてのメンバーについて、破棄を使用できます。 次の例は有効ですが、役に立ちません。

var (_, _, _) = tuple2;

レコードの分解

プライマリ コンストラクターを持つレコード型は、位置指定パラメーターの分解をサポートします。 コンパイラは、プライマリ コンストラクターの位置パラメーターから合成されたプロパティを抽出する Deconstruct メソッドを合成します。 コンパイラによって合成された Deconstruction メソッドは、レコード型のプロパティとして宣言されたプロパティを抽出しません。

次のコードに示す record では、SquareFeetAddressの 2 つの位置指定プロパティと、別のプロパティ 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 メソッドの各パラメーターの型は、分解式の対応する引数の型と一致する必要があります。 分解式は、各引数の値を、Deconstruct メソッド内の対応する out パラメーターの値に割り当てます。 複数の Deconstruct メソッドが分解式と一致する場合、コンパイラはあいまいさのエラーを報告します。

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

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;
    }
}

1 つ目のメソッドでは、XY、および Zの 3 つの軸の値をすべて抽出する分解式がサポートされています。 2 番目のメソッドでは、平面値 (XY) のみを分解できます。 最初のメソッドの アリティ は 3 です。2 番目の値のアリティは 2 です。

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

コンパイラが分解式に対して 1 つの一意の Deconstruct メソッドを決定できる限り、複数の Deconstruct メソッドが許可されます。 通常、同じ型の複数の Deconstruct メソッドには、異なる数のパラメーターがあります。 パラメーターの型によって異なる複数の Deconstruct メソッドを作成することもできます。 ただし、多くの場合、Deconstruct メソッドが多すぎると、あいまいなエラーや誤解を招く結果につながる可能性があります。

C# 言語仕様

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

関連項目