複数のデータをやりとりする場合、クラスや構造体を使う必要であったけど、

複数のデータを扱うことができるのがタプル型

例えば、二つの整数値から商と余りを求める場合

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; }
    }
}
投稿日時: 2025-06-23 14:36:23
更新日時: 2025-06-23 14:59:23

関数の中に関数を書くと、ローカル関数と呼ばれます

あまり現実的な例ではないですが、こういう感じで書けます

class SampleCode
{
    public void Sample()
    {
        void Output(string msg)
        {
            Console.WriteLine(msg);
        }

        Output("Hello C#");
    }
}

ローカル関数の外で宣言している変数名をローカル関数内で使用すると参照することができます

var obj = new SampleCode();
obj.Sample();

class SampleCode
{
    public void Sample()
    {
        var msg = "Hello C#!!";

        void Output()
        {
            Console.WriteLine(msg);
        }

        Output();
    }
}

本当は、ローカル関数の外側を参照させる意図がなかったのにうっかり参照してしまうケースを避けるために
staticをつけることで、静的ローカル関数が定義でき、この場合は外側で宣言した変数を参照することができなくなります

静的ローカル関数

var obj = new SampleCode();
obj.Sample();

class SampleCode
{
    public void Sample()
    {
        var msg = "Hello C#!!";

        static void Output()
        {
            Console.WriteLine(msg); // エラーになる
        }

        Output();
    }
}
投稿日時: 2025-06-23 12:59:23

C#には、型推論として var があります

C#3.0(2007年)に導入されたもののため、何気に古くから存在する機能です

右辺から型が推論できれば、varをかくだけでよいというものです

Dictionary<string, int> data1 = new Dictionary<string, int>();

var data2 = new Dictionary<string, int>();

インスタンス化する場合もvarで書くことはできますが・・・

C#9.0からは、左辺に型がかいてあれば右辺で省略ができます

var obj1 = new DateTime(); // 従来からある型推論

DateTime obj2 = new(); // C#9.0~

左辺でvarとするか右辺を省略するかの違いですが、右辺の場合初期値設定ができる分省略できる量が増えるってとこがポイントなんですかねぇ

// 省略なし
Dictionary<string, List<int>> field1 = new Dictionary<string, List<int>>() { { "item1", new List<int>() { 1, 2, 3 } } };

// varキーワード
var field2 = new Dictionary<string, List<int>>() { { "item1", new List<int>() { 1, 2, 3 } } };

// C#9.0のtarget-typed new式
Dictionary<string, List<int>> field3 = new() { { "item1", new() { 1, 2, 3 } } };

初期値設定まで考慮したら確かに差は大きいですね
https://github.com/dotnet/csharplang/blob/main/proposals/csharp-9.0/target-typed-new.md

投稿日時: 2025-06-23 12:45:23

最近の投稿

最近のコメント

タグ

アーカイブ

その他