忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

switchとパターン C#7.0メモ

C#7.0の新機能パターンマッチングのメモです。switchが便利になりました。


型を見るswitch

いままでは型を調べてキャストやら何やらしなくてはいけなかったところを、新機能できれいに書くことができます。

using System.Collections.Generic;

class GameModel
{
}

class Enemy : GameModel
{
    public int Health;
}

class Bullet : GameModel
{
    public int Power;
}

class Vehicle : GameModel { }

class Program
{
    static void Main()
    {
        var models = new List<GameModel>();
        var enemy = new Enemy();
        enemy.Health = 10;
        models.Add(enemy);
        var bullet = new Bullet();
        bullet.Power = 1;
        models.Add(bullet);
        models.Add(new Vehicle());
        draw(models);
    }

    static void draw(IEnumerable<GameModel> gameObjects)
    {
        foreach (var gameObject in gameObjects)
        {
            switch (gameObject)
            {
                case Enemy enemy:
                    System.Console.WriteLine("Enemy");
                    System.Console.WriteLine("  Health:" + enemy.Health);
                    break;
                case Bullet bullet:
                    System.Console.WriteLine("Bullet");
                    System.Console.WriteLine("  Power:" + bullet.Power);
                    break;
                default:
                    System.Console.WriteLine("<unknown>");
                    break;
            }
        }
    }
}

実行結果

Enemy
  Health:10
Bullet
  Power:1
<unknown>

switchが強力になりました!型によって分岐します。asやらisやらをあまり使わなくて良くなりそうです。

真偽値に反応するswitch

私はこれ好きです。

class Program
{
    static void Main()
    {
        writeFileType("myPicture.jpg");
        writeFileType("myDiary.txt");
    }

    static void writeFileType(string imageFileName)
    {
        switch (imageFileName)
        {
            case string jpg when jpg.EndsWith(".jpg"):
                System.Console.WriteLine("Image file");
                break;
            case string txt when txt.EndsWith(".txt"):
                System.Console.WriteLine("Text file");
                break;
        }
    }
}

実行結果

Image file
Text file

いままでのswitchはcaseに静的な情報しか書けませんでしたが、C#7.0からはこういう動的な式で条件分岐できます。if(){ } else if(){ }みたいなのを書く頻度が減りそうです。

混ぜて使う

条件つきのcaseと条件のないcaseを一緒に使うこともできます。

class Program
{
    static void Main()
    {
        writeFileType("myPicture.jpg");
        writeFileType("myDiary.txt");
        writeFileType("myMovie.webm");

        try
        {
            writeFileType(null);
        }
        catch (System.ArgumentException error)
        {
            System.Console.WriteLine(error.Message);
        }
    }

    static void writeFileType(string imageFileName)
    {
        switch (imageFileName)
        {
            case string jpg when jpg.EndsWith(".jpg"):
                System.Console.WriteLine("Image file");
                break;
            case string txt when txt.EndsWith(".txt"):
                System.Console.WriteLine("Text file");
                break;
            case string defaultType:
                System.Console.WriteLine("<unknown type>");
                break;
            case null:
                throw new System.ArgumentException(nameof(imageFileName) + "はnullではダメです");
        }
    }
}

実行結果

Image file
Text file
<unknown type>
imageFileNameはnullではダメです

条件が厳しいものを上にかいて、緩いものは下に書くようです。

拍手[0回]

PR