首页 > 编程语言 >C#的switch的用法

C#的switch的用法

时间:2022-10-31 20:11:52浏览次数:64  
标签:case Console C# value 用法 break switch WriteLine

  switch-case语句经常被认为是if-else语句的替代品,但是在众多程序语言中还是能见到switch的存在,这很大程度上是因为switch更实用,这一点在C#中更能提现。

  简单的语法就不说了,一个简单的switch用法:  

    switch (cmd)
    {
        case "start": Console.WriteLine("start"); break;
        case "pause": Console.WriteLine("pause"); break;
        case "stop": Console.WriteLine("stop"); break;
        default: Console.WriteLine("invalid commond"); break;
    }

  注意,C#规定,各个case语句不允许贯穿,也就是说每个case语句执行完之后,必须显示的退出,比如使用break、goto、return、throw等语句退出,但是C#又允许你使用goto case、goto default语句来实现贯穿(注意使用,避免造成死循环):  

    string color = "blue";
    switch (color)
    {
        case "red": Console.WriteLine("red"); goto default;
        case "green": Console.WriteLine("green"); goto case "red";
        case "blue": Console.WriteLine("blue"); goto case "green";
        default: Console.WriteLine("default"); break;
    }

    //输出:
    //blue
    //green
    //red
    //default

  虽然C#中switch不允许case贯穿,但是运行多个case语句组合:  

    switch (dayOfWeek)
    {
        case DayOfWeek.Monday: Console.WriteLine("weekend"); break;
        case DayOfWeek.Tuesday: Console.WriteLine("weekend"); break;
        case DayOfWeek.Wednesday: Console.WriteLine("weekend"); break;
        case DayOfWeek.Thursday: Console.WriteLine("weekend"); break;
        case DayOfWeek.Friday: Console.WriteLine("weekend"); break;
        case DayOfWeek.Saturday:
        case DayOfWeek.Sunday: Console.WriteLine("weekend"); break;
    }

  C# 6.0及之前版本的switch中,匹配表达式只支持字符串、字符、整形(如int、long等)、bool、枚举几个类型,因此switch的作用很有限,被认为是if-else的替代品也不无道理。

  C#7.0之后,switch的限制得到放宽,每个case语句不在是一个常量,而是一个模式,更多关于模式内容见:C#中的模式匹配

  看看一些简单的使用例子:

  1、声明模式  

    public void ShowMessage(object value)
    {
        switch (value)
        {
            case int i: Console.WriteLine($"value is int:{i}"); break;
            case long l: Console.WriteLine($"value is long:{l}"); break;
            case bool b: Console.WriteLine($"value is bool:{b}"); break;
            case string s: Console.WriteLine($"value is string:{s}"); break;
            default: Console.WriteLine($"value is object"); break;
        }
    }

  2、类型模式

  类型模式可以理解为在声明模式中使用了弃元:  

    public void ShowMessage(object value)
    {
        switch (value)
        {
            case int: Console.WriteLine($"value is int"); break;
            case long: Console.WriteLine($"value is long"); break;
            case bool: Console.WriteLine($"value is bool"); break;
            case string: Console.WriteLine($"value is string"); break;
            default: Console.WriteLine($"value is object"); break;
        }
    }

  3、常量模式

  常量模式可以理解为原来C#6.0及之前的用法:  

   switch (score)
   {
       case 10: 
       case 9: Console.WriteLine("excellent"); break;
       case 8: Console.WriteLine("good"); break;
       case 7: 
       case 6: Console.WriteLine("fair"); break;
       default: Console.WriteLine("poor"); break;
   }

  4、关系模式  

    switch (score)
    {
        case >= 80: Console.WriteLine("excellent"); break;
        case >= 60: Console.WriteLine("good"); break;
        default: Console.WriteLine("poor"); break;
    }

  5、逻辑模式  

    switch (value)
    {
        case 0: Console.WriteLine("value is 0"); break;
        case not 0 and (100 or -100): Console.WriteLine("abs(value)==100"); break;
        case not 0 and (> 0 and < 100): Console.WriteLine("value is positive and less than 100"); break;
        case not 0 and > 0: Console.WriteLine("value is positive and greater than 100"); break;
        case < -100 or (< 0 and > -100): Console.WriteLine("value is negative and not equals -100"); break;
    }

  6、属性模式

    switch (time)
    {
        case { Year: 2020 or 2021, Month: <= 6, Day: 1 } t: Console.WriteLine($"the first day of every month in the first half of 2020 and 2021"); break;
        case { Year: not 2022 }: Console.WriteLine($"not 2022"); break;
        case { DayOfWeek: not DayOfWeek.Sunday and not DayOfWeek.Saturday }: Console.WriteLine($"recursion"); break;
    }

  7、位置模式

  位置模式采用解构的特性来说明指定的模式是否匹配:  

    public record Point2D(int X, int Y);//记录可以解构
    static void Print(Point2D point)
    {
        switch (point)
        {
            case ( > 0, > 0): Console.WriteLine("first quadrant"); break;
            case ( < 0, > 0): Console.WriteLine("second quadrant"); break;
            case ( < 0, < 0): Console.WriteLine("third quadrant"); break;
            case ( > 0, < 0): Console.WriteLine("fourth quadrant"); break;
            default: Console.WriteLine("coordinate axis"); break;
        }
    }

  8、Var模式

  Var模式往往和属性模式和位置模式结合,用于提取属性变量值:  

    switch (point)
    {
        case (var x, var y, var z): Console.WriteLine($"3D point:({x},{y},{z})"); break;//在位置模式中使用
        case Point2D { X: var x, Y: var y }: Console.WriteLine($"2D point:({x},{y})"); break;//在属性模式中使用
        default: Console.WriteLine("others"); break;
    }

  9、弃元模式

  弃元模式在switch语句中用的不多,但是在switch表达式中使用的多:  

    var result = score switch
    {
        >= 80 => "excellent",
        >= 60 => "good",
        _ => "poor" //弃元在switch表达式中就相当于default
    };

 

  switch表达式

  从C#8.0开始,switch有了一种新的用法:switch表达式,它的主要就是类似于sql语句中的case-when的用法,可以方便的进行匹配输出,格式:  

    var_name switch 
    {
        match_expr1 => value1,
        match_expr2 => value2,
        match_expr3 => value3,
        _ => default_value
    }

  这里的每一个 match_expr 是一个匹配模式,相当于switch语句中的case语句的模式内容,它的含义就是,如果match_expr模式匹配成功,那么就返回对应的值,需要注意的是,switch表达式是输出语句!

  比如之前有这样的一个枚举:  

    public enum Color
    {
        Unknown,
        Red,
        Blue,
        Green
    }    

  使用中我们可能会需要进行一些转换,可能会用到 if 判断:  

    static string Convert(Color color)
    {
        string rbg;
        if (color == Color.Red)
        {
            rbg = "#FF0000";
        }
        else if (color == Color.Blue)
        {
            rbg = "#0000FF";
        }
        else if (color == Color.Green)
        {
            rbg = "#00FF00";
        }
        else
        {
            rbg = "";
        }
        return rbg;
    }

  或者使用switch语句:  

    static string Convert(Color color)
    {
        string rbg;
        switch (color)
        {
            case Color.Red:rbg = "#FF0000";break;
            case Color.Blue: rbg = "#0000FF"; break;
            case Color.Green: rbg = "#00FF00"; break;
            default: rbg = ""; break;
        }
        return rbg;
    }

  现在使用switch表达式可简写Convert方法:  

    static string Convert(Color color)
    {
        return color switch
        {
            Color.Red => "this is red",
            Color.Blue => "this is blue",
            Color.Green => "this is green",
            _ => "",
        };
    }

  这样看起简洁密聊了许多。

 

  case-when

  无论是在switch语句中,还是在switch表达式中,在模式匹配之后,我们可以跟着一个when语句,对匹配结果做进一步的判断:  

  比如一些简单的例子:    

    static string Convert(object color)
    {
        return color switch
        {
            Color c when c == Color.Red => "red",
            Color c when c == Color.Blue => "blue",
            Color c when c == Color.Green => "green",
            _ => "unknown color",
        };
    }

  再比如:

    var desc = shape switch
    {
        Point p when p.IsEmpty => "empty point",
        Point { X: var x, Y: var y } when object.Equals(x, y) => "point:x=y",
        Point => $"point",
        Rectangle { Width: var width, Height: var height } when width == height => "square",
        Rectangle => "rectangle",
        _ => "other shape"
    };

  when语句弥补了模式的一些不足,可以让判断更加精确而不用我们自己在后续代码中使用if语句进行判断。

  

标签:case,Console,C#,value,用法,break,switch,WriteLine
From: https://www.cnblogs.com/shanfeng1000/p/14951498.html

相关文章

  • C++案例
    错误1:类加了括号 错误2:内存泄漏:  源代码:    ......
  • object类
    所有类的父类,可以说是超级父类,他有的方法所有类都有:protectedObjectclone();//获得一个对象的副本默认浅克隆booleaneuqals(Objectobj)inthashcode();//与equals......
  • 【CF1292F】Nora's Toy Boxes(状压DP)
    考虑将点分为$A,B$两类。其中$[x\inA]\iff\exists_{y\neqx},y|x$。那么我们删去的点只可能在$B$类中,且当前$x\inB$可删当且仅当存在$y\inB,z\inA$使得$z|x......
  • CSP-S 2022游记
    怎么会有人考完几天之后才写总结的啊-Day???快乐的信竞(摆烂)生活!tlryyyds-Day?每天考试和改题ing...-Day0上午摆烂,下午考模拟赛(信心消失赛)试用了考试的键盘有......
  • Qt制作简单和高级SplashScreen(程序启动页面)
    一、简单的制作SplashScreenQt本来自带QSplashScreen类,这个简单的类提供了个简单的方法就是在程序启动前提供一个图片让其先启动,等我们主程序启动后这个启动页面消失。可以......
  • QML与QWidget简单的联合使用(QQuickWidget衔接)
    如果碰到这种情况,可能软件整体并不复杂也不需要太多炫酷的效果,此时我们可能选择QWidget体系来做。但是,可能某个小部件又非常需要炫酷的效果,QWidget并不是我们此时想要的,可以......
  • 用IntersectionObserver来处理已读未读
    *参考地址:IntersectionObserver-WebAPI接口参考|MDN(mozilla.org)一、IntersectionObserver的使用场景主要用来监听目标元素和指定的根元素之间,在滚动界面的时......
  • C++面向对象高级开发(六)写好一个String类
    类的内部:public:构造函数、拷贝构造、拷贝赋值、析构函数的接口和辅助函数以及它的实现private:参数  类的外部:内联:inline构造函数:判断是否有初值:有初值:分配......
  • 转: docker-compse build 镜像指定版本 tag
    转: https://stackoverflow.com/questions/56082506/docker-compose-build-with-new-tagIhaveadocker-composewhichlookslike:version:'3.2'services:jobsaf......
  • Kubecm-多集群kubectl 管理工具
    Kubecm-多集群kubectl管理工具https://github.com/sunny0826/kubecmhttps://kubecm.cloud/en-us/README......