2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C#の条件分岐についてのアウトプット

Posted at

C#の条件分岐について学んだことをアウトプットします。

確認は .NET9 で行っています。

if文

if文に関してはC系統の言語によくある書き方です。
ifif elseelseの書き方ができます。

C#
var names = new[] { "紫咲シオン", "宝鐘マリン", "雪花ラミィ" };

foreach(var name in names)
{
    if (name == "紫咲シオン")
    {
        Console.WriteLine("塩っ子");
    }
    else if (name == "宝鐘マリン")
    {
        Console.WriteLine("宝鐘の一味");
    }
    else
    {
        Console.WriteLine("雪民");
    }
}

// 塩っ子
// 宝鐘の一味
// 雪民

switch文

こちらも基本の書き方はC系統に似た書き方です。

条件には数値、文字、文字列、列挙型、タプルが指定できます。

C#のswitch文は文の末尾、またはdefaultまでにbreakが必ず必要です。
またdefalutにもbreakがないとビルドエラーになります。

C#
var names2 = new[] 
{ 
    "Shion", "塩っ子", 
    "Marine", "宝鐘の一味", 
    "Lamy", "雪民" 
};

foreach (var name in names2)
{
    switch (name)
    {
        case "Shion": case "塩っ子":
            Console.WriteLine("紫咲シオン");
            break;
        case "Marine": case "宝鐘の一味":
            Console.WriteLine("宝鐘マリン");
            break;
        default:
            Console.WriteLine("雪花ラミィ");
            break;
    }
}

// 紫咲シオン
// 紫咲シオン
// 宝鐘マリン
// 宝鐘マリン
// 雪花ラミィ
// 雪花ラミィ

条件をつけて比較することも可能です。

C#
var month = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };

foreach (var m in month)
{
    switch(m)
    {
        case >= 3 and < 6:
            Console.WriteLine($"{m}は春です。");
            break;
        case >= 6 and < 9:
            Console.WriteLine($"{m}は夏です。");
            break;
        case >= 9 and < 12:
            Console.WriteLine($"{m}は秋です。");
            break;
        case 12 or (>= 1 and < 3):
            Console.WriteLine($"{m}は冬です。");
            break;
        default:
            Console.WriteLine("存在しない月です。");
            break;
    }
}

// 1は冬です。
// 2は冬です。
// 3は春です。
// 4は春です。
// 5は春です。
// 6は夏です。
// 7は夏です。
// 8は夏です。
// 9は秋です。
// 10は秋です。
// 11は秋です。
// 12は冬です。
// 存在しない月です。

タプルでの比較

C#
var names3 = new[]
{
    ("Shion", "紫咲シオン"),
    ("Marine", "宝鐘マリン"),
    ("Lamy", "雪花ラミィ"),
};

foreach (var name in names3)
{
    switch(name)
    {
        case ("Shion", "紫咲シオン"):
            Console.WriteLine("塩っ子");
            break;
        case ("Marine", "宝鐘マリン"):
            Console.WriteLine("宝鐘の一味");
            break;
        case ("Lamy", "雪花ラミィ"):
            Console.WriteLine("雪民");
            break;
    }
}

// 塩っ子
// 宝鐘の一味
// 雪民

タプル型でも条件を付けた比較を行えます。

C#
var points2 = new[] { (10, 20), (20, 20), (20, 10), (10, 0) };

foreach (var point in points2)
{
    switch (point)
    {
        case (>= 10, >= 10):
            Console.WriteLine($"条件に一致したポイントは{point}です。");
            break;
        case (<= 10, <= 10):
            Console.WriteLine($"条件に一致したポイントは{point}です。");
            break;
        default:
            Console.WriteLine($"条件に一致したポイントはありませんでした。");
            break;
    }
}

// 条件に一致したポイントは(10, 20)です。
// 条件に一致したポイントは(20, 20)です。
// 条件に一致したポイントは(20, 10)です。
// 条件に一致したポイントは(10, 0)です。

whenをつけることで更に詳細な条件を指定できます。
これをケースガードというようです。

C#
var points2 = new[] { (10, 20), (20, 20), (20, 10), (10, 10) };

foreach(var point in points2)
{
    switch (point)
    {
        case ( <= 20, <= 20) when point.Item1 == point.Item2:
            Console.WriteLine($"条件に一致したポイントは{point}です。");
            break;
        default:
            Console.WriteLine($"{point}は条件に一致しませんでした。");
            break;
    }
}

// (10, 20)は条件に一致しませんでした。
// 条件に一致したポイントは(20, 20)です。
// (20, 10)は条件に一致しませんでした。
// 条件に一致したポイントは(10, 10)です。

switch式

C#のswitch文は式として扱うことも可能です。
switchで評価した値を変数に直接代入することが可能です。

以下のように記述します。

C#
var {変数名} = {比較元} switch
{
    {比較先} => {結果},
    {比較先} => {結果},
    :
    :
    _ => {不一致結果},
}

caseは使用せずに、比較値 => 結果という形式になります。
いずれにも一致しなかった場合のdefalutはアンダースコア(_)を使用します。

C#
var names4 = new[] { "塩っ子", "宝鐘の一味", "雪民", "ミオファ" };

foreach (var name in names4)
{
    var value = name switch
    { 
        "塩っ子" => "紫咲シオン",
        "宝鐘の一味" => "宝鐘マリン",
        "雪民" => "雪花ラミィ",
        _ => "対応する名前が見つかりません。",
    };

    Console.WriteLine($"名前:{value}");
}

// 名前:紫咲シオン
// 名前:宝鐘マリン
// 名前:雪花ラミィ
// 名前:対応する名前が見つかりません。

パターンマッチング

is式、switch文、switch式を使用して特定のパターンに一致するか検証できます。

宣言パターン

指定された型と一致した場合に、後続で指定した変数に代入されます。

C#
var data = new List<object> { 1208, "紫咲シオン", 'S' };

data.ForEach(item =>
{
    var message = item switch
    {
        string shion => $"{shion}のファンネームは塩っ子です。",
        int birthday => $"誕生日は{birthday}です。",
        char initial => $"イニシャルは{initial}です。",
        _ => "想定外の型が指定されました。",
    };

    Console.WriteLine(message);
});

// 誕生日は1208です。
// 紫咲シオンのファンネームは塩っ子です。
// イニシャルはSです。

型パターン

変数を使用しない宣言パターンを型パターンというらしいです。

C#
var data2 = new List<object> { 1208, "紫咲シオン", 'S' };

data2.ForEach(item =>
{
    var message = item switch
    {
        string _ => $"塩っ子",
        int _ => "12月8日",
        char _ => "N",
        _ => "想定外の方が指定されました。"
    };

    Console.WriteLine(message);
});

// 12月8日
// 塩っ子
// N

定数パターン

今まで記述していたif、switchのような書き方を定数パターンというようです。

C#
var names = new[] { "紫咲シオン", "宝鐘マリン", "雪花ラミィ" };

foreach (var name in names)
{
    switch (name)
    {
        case "紫咲シオン":
            Console.WriteLine("塩っ子");
            break;
        case "宝鐘マリン":
            Console.WriteLine("宝鐘の一味");
            break;
        case "雪花ラミィ":
            Console.WriteLine("雪民");
            break;
    }
}

// 塩っ子
// 宝鐘の一味
// 雪民

リレーショナルパターン

caseに条件を加えたパターンをリレーショナルパターンというようです。

C#
var points = new[] { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };

foreach (var point in points)
{
    switch(point)
    {
        case >= 80:
            Console.WriteLine($"{point}点は優秀です。");
            break;
        case >= 60:
            Console.WriteLine($"{point}点はほどほどです。");
            break;
        case >= 40:
            Console.WriteLine($"{point}点はまずいです。");
            break;
        default:
            Console.WriteLine($"{point}点は絶望的です。");
            break;
    }
}

// 10点は絶望的です。
// 20点は絶望的です。
// 30点は絶望的です。
// 40点はまずいです。
// 50点はまずいです。
// 60点はほどほどです。
// 70点はほどほどです。
// 80点は優秀です。
// 90点は優秀です。
// 100点は優秀です。

論理パターン

notandorで条件を繋げるパターンのことです。

C#
var items = new[] { -30, -20, -10, 0, 10, 20, 30 };

foreach (var item in items)
{
    var result = item switch
    {
        <= 30 and > 0 => $"{item}は0以上30以下です。",
        <= -20 or >= 20 => $"{item}はー20以下または20以上です。",
        not -30 and not -10 and not 10 and not 30 => $"{item}はー30、ー10、10、30以外です。",
        _ => $"{item}はいずれの条件にも一致しませんでした。",
    };

    Console.WriteLine(result);
}

// -30はー20以下または20以上です。
// -20はー20以下または20以上です。
// -10はいずれの条件にも一致しませんでした。
// 0はー30、ー10、10、30以外です。
// 10は0以上30以下です。
// 20は0以上30以下です。
// 30は0以上30以下です。

プロパティーパターン

一致した型のプロパティー値を比較することをいうようです。

C#
var names2 = new[] { "MURASAKI SHION", "OOKAMI MIO", "YUKIHANA LAMY" };

foreach (var name in names2)
{
    var message = name switch
    {
        string { Length: >= 14 } s => $"{s}は紫咲シオンです。",
        string { Length: >= 13 } s => $"{s}は雪花ラミィです。",
        string { Length: >= 10 } s => $"{s}は大神ミオです。",
        _ => "いずれにも該当しません"
    };

    Console.WriteLine(message);
}

// MURASAKI SHIONは紫咲シオンです。
// OOKAMI MIOは大神ミオです。
// YUKIHANA LAMYは雪花ラミィです。

入れ子になっているプロパティもアクセス可能です。
型 プロパティ: {プロパティ: 比較値}というアクセス方法と型 { プロパティ.プロパティ: 比較値}というアクセス方法があります。

後者を拡張プロパティパターンと呼ぶようです。

C#
namespace Program;

class Program()
{
    public static void Main()
    {
        var members = new[]
        { 
            new Member("塩っ子"), new Member("宝鐘の一味"), new Member("雪民") 
        };

        foreach (var member in members)
        {
            var name = member switch
            {
                Member { Fun.Name: "塩っ子" } => "紫咲シオン",
                Member { Fun.Name: "宝鐘の一味" } => "宝鐘マリン",
                Member { Fun: { Name: "雪民" } } => "雪花ラミィ",
                _ => "いずれにも該当しません。",
            };

            Console.WriteLine($"{member.Fun.Name}{name}が好きです。");
        }
    }
}


class Fun(string name)
{
    public string Name { get; set; } = name;
}
class Member(string name)
{
    public Fun Fun { get; set; } = new Fun(name);
}

// 塩っ子は紫咲シオンが好きです。
// 宝鐘の一味は宝鐘マリンが好きです。
// 雪民は雪花ラミィが好きです。

位置指定パターン

タプル型で使用したようなパターンのことのようです。
ただ、これだけではないようで、まだその部分に関しては勉強中です。

C#
var points2 = new[] 
{ 
    (0, 0), (0, 1), (0, 2), 
    (1, 0), (1, 1), (1, 2),
    (2, 0), (2, 1), (2, 2),
};

foreach (var point in points2)
{
    var message = point switch
    {
        (0, 0) => $"{point}は左下です。",
        (1, 1) => $"{point}は中央です。",
        (2, 2) => $"{point}は右上です。",
        _ => $"{point}はどこかにあるでしょう。",
    };

    Console.WriteLine(message);
}

// (0, 0)は左下です。
// (0, 1)はどこかにあるでしょう。
// (0, 2)はどこかにあるでしょう。
// (1, 0)はどこかにあるでしょう。
// (1, 1)は中央です。
// (1, 2)はどこかにあるでしょう。
// (2, 0)はどこかにあるでしょう。
// (2, 1)はどこかにあるでしょう。
// (2, 2)は右上です。

varパターン

使い方のイメージがいまいち沸かず、勉強中です。

リストパターン

リストの内容が一致するかを検証するパターンのようです。
[値, 値, 値, ...]のような形式で指定します。

C#
var numbers = new List<int>() { 10, 20, 30 };
Console.WriteLine($"numbers is [> 5, 20, 3 or 30] = {numbers is [> 5, 20, 3 or 30]}");
Console.WriteLine($"numbers is [10, 50, 30] = {numbers is [10, 50, 30]}");
Console.WriteLine($"numbers is [10, 20, 30, 40] = {numbers is [10, 20, 30, 40]}");

// numbers is [> 5, 20, 3 or 30] = True
// numbers is [10, 50, 30] = False
// numbers is [10, 20, 30, 40] = False

条件を先頭や末尾などの一部だけに指定したい場合、検証しない部分を..で指定できます。

C#
var numbers2 = new List<int>() { 10, 20, 30, 40, 50 };
Console.WriteLine($"numbers2 is [10, .., 50] = {numbers2 is [10, .., 50]}");

// numbers2 is [10, .., 50] = True
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?