PR

[C# 入門] switch式を使って変数の値や型によって異なる値を返す

今回はswitch式についてです。
switch式はC#8.0から使うことができます。
switch式を使うと、指定された変数の値や型によって異なる値を返すことができます。

switch文とは違いcase、break、defaultキーワードを使わず書くことが出来ます。

スポンサーリンク

switch式の使い方

こんな感じです。

using System;

class Program
{
    public static void Main()
    {
        // switch式で使う変数
        int number = 20;

        // switch式でnumberの値によって変数messageに入れる文字を切り替える
        string message = number switch
        {
            10 => "numberは10でした。",
            20 => "numberは20でした。",
            30 => "numberは30でした。",
            _ => "10、20、30以外でした。",
        };

        // メッセージを表示
        Console.WriteLine(message);
    }
}
numberは20でした。

11行目の「number switch」から17行目がswitch式を使っているところです。
switch式はというくらいなので結果を返します。
上のコードの場合、switchの前に指定された変数numberの値によって何を返すのかが決まり、変数messageにその結果が代入されます。

switch式がどんな値を返すかを指定しているのが12行目から17行目の { } 内になります。
{ } 内に書いたこんな時はこんな値を返すという式をアームというらしいです。
switch文と同じで上から順にみていき当てはまったらその値を返します(上に書いてあるアームほどが優先順位が高い)。

ちなみに一番最後のアンダーバー「 _ 」はそれより前にあるアームに当てはまらなかった場合にどんな値を返すのか指定するものです。switch式は必ず何かしらの値を返さないといけないので、_ を使用してすべてのパターンを網羅します。(switch文のdefaultみたいな感じです。)

もうひとつ、{ } を使って「それより上のアームで一致しなかったnull以外の場合」というのを指定することができます。

using System;
class Program
{
    public static void Main()
    {
        int? number = 10;

        string message = number switch
        {
            1 => "numberには1が入っています。",
            2 => "numberには1が入っています。",
            { } => "null以外の何かしらの数値が入っています。",
            _ => "想定外の値が入っています。",
        };

        // メッセージを表示
        Console.WriteLine(message);
    }
}
null以外の何かしらの数値が入っています。
スポンサーリンク

指定した変数の型に応じた値を返す

switch式の { } 内を int i => 返したい値を返す式 みたいな感じにすると、型が一致した場合に変数(この場合 i )に変換された値が代入され、=> の右辺でその変数を使って値を返すことができます。

using System;
using System.Collections.Generic;

class Program
{
    public static void Main()
    {
        // 型が分からない変数
        object number = 10.0;

        // switch式で型に応じたメッセージを返す
        string message = number switch
        {
            int i    => $"numberはint型 = {i}",
            float f  => $"numberはfloat型 = {f}",
            double d => $"numberはdouble型 = {d}",
            string s => $"numberはstring型 = {s}",
            List<int> list => $"numberはList<int>型 = {list}",
            _        => "unknown",
        };

        // メッセージを表示
        Console.WriteLine(message);
    }
}
numberはdouble型 = 10
スポンサーリンク

プロパティの値に応じた値を返す

{ プロパティ名: 値 } => 値を返す式 という風にすると、指定したクラスのプロパティに応じた値を返すことができます。

using System;

class Sample 
{ 
    public int Number { get; set; }
    public string Name { get; set; }
}

class Program
{
    public static void Main()
    {
        // Sampleクラスを作成してプロパティに初期値をセット
        Sample cls = new Sample { Number = 10, Name = "YasNote" };

        // Sampleクラスのプロパティ(Number)の値に応じたメッセージを返す
        string message = cls switch
        {
            { Number: 1 } => "プロパティNumberは1でした。",
            { Number: 5 } => "プロパティNumberは5でした。",
            { Number: 10 } => "プロパティNumberは10でした。",
            _ => $"プロパティNumberは想定外の値でした。{cls.Number}",
        };

        // メッセージを表示
        Console.WriteLine(message);
    }
}
プロパティNumberは10でした。

また、カンマで区切ってプロパティを複数指定することもできます。

using System;

class Sample
{
    public int Number { get; set; }
    public string Name { get; set; }
}

class Program
{
    public static void Main()
    {
        // Sampleクラスを作成してプロパティに初期値をセット
        Sample cls = new Sample { Number = 10, Name = "YasNote" };

        // Sampleクラスのプロパティ(Number, Name)の値に応じたメッセージを返す
        string message = cls switch
        {
            { Number: 1, Name: "aaa" } => "Numberは1で、Nameはaaaでした。",
            { Number: 10, Name: "aaa" } => "Numberは10で、Nameはaaaでした。",
            { Number: 10, Name: "YasNote" } => "Numberは10で、NameはYasNoteでした。",
            _ => $"プロパティは想定外の値でした。",
        };

        // メッセージを表示
        Console.WriteLine(message);
    }
}
Numberは10で、NameはYasNoteでした。

プロパティの型に応じた値を返すこともできます。こんな感じ、

using System;

class Sample 
{ 
    public object Object { get; set; }
}

class Program
{
    public static void Main()
    {
        // Sampleクラスを作成してプロパティに初期値をセット
        Sample cls = new Sample { Object = "YasNote" };

        // Sampleクラスのプロパティ(Object)の型に応じたメッセージを返す
        string message = cls switch
        {
            { Object: string s } => $"プロパティObjectはstring型でした。{s}",
            { Object: int i } => $"プロパティObjectはint型でした。{i}",
            _ => "プロパティObjectは想定外の型でした。",
        };

        // メッセージを表示
        Console.WriteLine(message);
    }
}
プロパティObjectはstring型でした。YasNote
スポンサーリンク

タプルに応じた値を返す

タプルに応じた値を返すこともできます。

using System;

class Program
{
    public static void Main()
    {
        int number = 10;
        string name = "yasnote";

        // タプルの値に応じたメッセージを返す
        string message = (number, name) switch
        {
            (1, "aaa") => "メッセージ1",
            (2, "bbb") => "メッセージ2",
            (_, "ccc") => "これはname部分だけを見るパターン",
            (10, "yasnote") => "(10, \"yasnote\")だったよ",
            _ => $"想定外の値でした。",
        };

        // メッセージを表示
        Console.WriteLine(message);
    }
}
(10, "yasnote")だったよ

タプルについて詳しく知りたい方はこちらをどうぞ、

[C# 入門] タプル(tuple)の使い方まとめ
今回はタプルについてです。 わりと新しめの機能で、データ型の1つになります。タプル型の変数は一つの変数に複数の値を格納できます。これを使うとメソッドの戻り値に複数の値を返せるようになったりします。 1つの変数で複数の値って配列もそうでは?と...
スポンサーリンク

when句でさらに条件を付ける

when句を使うとさらに条件を付けることができます。
whenの後ろにbool値を返す式を指定します。その式の結果がtrueにならないと条件をみたしたことになりません。

下のコードは、型が一致(int型)していて、その数値の範囲によって返す値を変えている。

using System;

class Program
{
    public static void Main()
    {
        // 型が分からない変数
        object number = 10;

        // switch式で型と条件に応じたメッセージを返す
        string message = number switch
        {
            int i when i < 1 => $"numberはint型で値は1より小さい。number = {i}",
            int i when i < 10 => $"numberはint型で値は10より小さい。number = {i}",
            int i when i < 20 => $"numberはint型で値は20より小さい。number = {i}",
            int i => $"numberはint型 = {i}",
            _ => "unknown",
        };

        // メッセージを表示
        Console.WriteLine(message);
    }
}
numberはint型で値は20より小さい。number = 10

C# 記事まとめページに戻る(他のサンプルコードもこちら)

C# プログラミング講座
C#についての記事まとめページです。開発環境VisualStudioのインストール方法や使い方、プログラミングの基礎知識についてや用語説明の記事一覧になっています。講座の記事にはすぐに実行できるようにサンプルコードを載せています。

コメント