【C#】タプル(Tuple / ValueTuple)の使い方と利点

C# では複数の値をひとまとめに扱いたいときに「タプル(Tuple)」が利用できます。クラスや構造体をわざわざ定義しなくても、一時的に複数の値を返す・渡すといった用途に便利です。C# 7.0 以降では ValueTuple が導入され、より直感的で効率的に使えるようになりました。本記事では Tuple と ValueTuple の違いと使い方を解説します。

Tupleクラスの基本

旧来からある System.Tuple クラスは、複数の値をまとめることができます。

using System;

class Program
{
    static void Main()
    {
        Tuple<string, int> person = Tuple.Create("Taro", 20);

        Console.WriteLine(person.Item1); // Taro
        Console.WriteLine(person.Item2); // 20
    }
}

ただしプロパティ名が Item1, Item2 などとなり、可読性に欠けます。

ValueTuple(C# 7.0以降)の基本

C# 7.0 からは ValueTuple が導入され、より直感的に扱えるようになりました。
また Item1 のような名前ではなく、カスタム名を付けられるため可読性が向上します。

class Program
{
    static void Main()
    {
        (string Name, int Age) person = ("Hanako", 18);

        Console.WriteLine(person.Name); // Hanako
        Console.WriteLine(person.Age);  // 18
    }
}

メソッドの戻り値として使う

タプルはメソッドの戻り値に複数の値を返したい場合に特に便利です。

static (int min, int max) GetMinMax(int[] numbers)
{
    int min = int.MaxValue;
    int max = int.MinValue;

    foreach (var n in numbers)
    {
        if (n < min) min = n;
        if (n > max) max = n;
    }
    return (min, max);
}

static void Main()
{
    int[] data = { 5, 2, 9, 1, 7 };
    var result = GetMinMax(data);

    Console.WriteLine($"最小値: {result.min}, 最大値: {result.max}");
}

分解(Deconstruction)

タプルの値を変数に直接展開(分解)することも可能です。

var person = ("Ken", 30);
(string name, int age) = person;

Console.WriteLine(name); // Ken
Console.WriteLine(age);  // 30

TupleとValueTupleの違い

項目 Tuple ValueTuple
導入バージョン C# 4.0 C# 7.0
参照型(クラス) 値型(構造体)
プロパティ名 Item1, Item2, … 任意の名前を付与可能
性能 参照型のためGCの影響あり 値型で軽量、効率的

まとめ

C# のタプルは「一時的に複数の値をまとめたい」ときに便利な機能です。

  • Tuple は従来からある参照型、ValueTuple は C# 7.0 以降の値型
  • ValueTuple では名前付きフィールドを使えるため可読性が高い
  • メソッドの戻り値やデータの分解に活用できる

日常的な開発では ValueTuple を使うのが主流です。特にメソッドの複数戻り値や一時的なデータ保持に活用してみましょう。