複数のデータをやりとりする場合、クラスや構造体を使う必要であったけど、
複数のデータを扱うことができるのがタプル型
例えば、二つの整数値から商と余りを求める場合
Math.DivRemを使うと以下のようにかけます
using System;
public class Sample
{
    public static void Main(string[] args)
    {
        var dividend = 10;
        var divisor = 3;
        // Math.DivRem メソッドで商と余りを取得
        var quotient = Math.DivRem(dividend, divisor, out var remainder);
    }
}
これを自作関数でタプルを使って表現すると
public class Sample 
{
    public static void Main(string[] args)
    {
        var dividend = 10;
        var divisor = 3;
        // Math.DivRem メソッドで商と余りを取得
        var (quotient, remainder) = DivRim(dividend, divisor);
    }
    static (int, int) DivRim(int dividend, int divisor)
    {
        var quotient = dividend / divisor;
        var remainder = dividend % divisor;
        return (quotient, remainder);
    }
}
戻り値で、構造体、クラス定義せずに複数の異なる値を返せるのは楽でよいですね
変数宣言して利用する場合は、以下のように記述する
using System;
public class Sample
{
    public static void Main(string[] args)
    {
        // ■タプルのリテラル(Item1, Item2でアクセスできる)
        var data = (10, 3);
        Console.WriteLine($"値1:{data.Item1}, 値2:{data.Item2}");
        // ■タプルの要素に名前をつけることもできる
        var data2 = (a: 10, b: 3);
        Console.WriteLine($"値1:{data2.a}, 値2:{data2.b}");
        // ■型を指定して受ける場合
        (float, float) data3 = (2, 3);
        Console.WriteLine($"値1:{data3.Item1}, 値2:{data3.Item2}");
    }
}
XYZの座標をもつ点の情報を扱うのであれば、今まで構造体やクラスを用意していたものがお手軽に扱えるのはよいですね
using System;
public class Sample
{
    public static void Main(string[] args)
    {
        // 構造体の場合
        var data1 = new XYZ { X=1, Y=2, Z=3};
        // タプルの場合
        var data2 = (x: 1, y: 2, z: 3);
    }
    struct XYZ
    {
        public int X { get; set; }
        public int Y { get; set; }
        public int Z { get; set; }
    }
}