C#的Switch语句2(case后的值与模式匹配)

2024-06-20 08:12

本文主要是介绍C#的Switch语句2(case后的值与模式匹配),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • switch语法结构
  • case
    • 具体的值
    • 枚举值
    • 字符串
    • const关键字
  • 如果没有匹配的值
    • default语句不一定要在最后
  • 模式匹配
  • 与C++的差异-case穿透(Fall-through)
  • 下一篇文章

switch语法结构

基础的语法结构,在上一篇文章已经写了,具体请看:
点击链接跳转

case

具体的值

在上一篇文章提到过,Switch语句是一种选择结构,用于基于某个表达式的值来执行多个可能代码路径中的一个。这里的关键词是“离散值”,意味着Switch只能用于比较具体的、不可变的值,比如数字、枚举成员或者字符串(从C# 7.0开始支持)。它不适用于比较操作,比如大于、小于或等于这样的条件表达式。例如类似“如果速度大于60公里”的连续范围条件。但这个比较操作也不绝对,后面会讲解模式匹配,届时大家便会对这个比较操作有一个新看法。
例如:

switch (dayOfWeek)
{case 1:Console.WriteLine("星期一");break;case 2:Console.WriteLine("星期二");break;
}

并且case标签后面要跟着一个常量表达式(const expression),这意味着它必须是一个在编译时就可以确定的值。这些值可以是整数、字符、枚举成员或者是字符串(从C# 7.0开始支持)。这里的“const”虽然没有直接体现在语法关键字上,但体现了case标签值需要具有静态确定性的原则。

上面的示例中,1和2,就是常规的常量例子。

枚举值

枚举值也是常量表达式的一种,它们在编译时就已经确定:

    enum Color { Red, Green, Blue };static void Main(){Color favoriteColor = Color.Green;switch (favoriteColor){case Color.Red:Console.WriteLine("最喜欢的颜色是红色");break;case Color.Green: // 枚举是一个const表达式Console.WriteLine("最喜欢的颜色是绿色");break;case Color.Blue:Console.WriteLine("最喜欢的颜色是蓝色");break;}}

字符串

从C# 7.0起,字符串也可以作为switch的表达式,同样遵循编译时常量的原则:

        string day = "Monday";switch (day){case "Sunday":Console.WriteLine("今天是星期日");break;case "Monday": // 这是一个const表达式Console.WriteLine("今天是星期一");break;// ...其他cases...}

const关键字

const关键字用于定义编译时常量,其值在编译期间就必须是已知的,并且之后不能更改。

使用const定义case标签值的情况:

        const int OPTION_ONE = 1;const int OPTION_TWO = 2;const int OPTION_THREE = 3;int selection = OPTION_THREE;switch (selection){case OPTION_ONE:Console.WriteLine("选择了选项一");break;case OPTION_TWO:Console.WriteLine("选择了选项二");break;case OPTION_THREE:Console.WriteLine("选择了选项三");break;default:Console.WriteLine("无效的选择");break;}

在这个例子中,尽管使用了const关键字,但重要的是理解case标签后需要的是常量表达式这一特性,而非const关键字。

如果没有匹配的值

在Switch语句中,如果没有匹配的值要怎么办?这时候我们就需要使用default关键字了,default定义了一个默认的代码块,当Switch表达式的值与任何一个case标签的值都不匹配时,程序会执行default语句块中的代码。这在处理未预期或不明确的输入值时非常有用,确保了代码的健壮性,避免了因没有匹配的case而直接跳过Switch结构导致的潜在问题。

default语句可以在Switch语句的任何位置出现,但通常推荐将其放在所有case之后,这样可以清晰地表明它是最后的兜底处理。

延续之前的星期几示例,我们加入default语句处理无效的输入:

int dayOfWeek = 8; // 故意设置一个无效的天数
switch (dayOfWeek)
{case 1:Console.WriteLine("星期一");break;case 2:Console.WriteLine("星期二");break;// ... 其他case省略 ...case 7:Console.WriteLine("星期日");break;default:Console.WriteLine("无效的天数输入");break;
}

在这个例子中,当dayOfWeek的值不是1到7之间的整数时,程序会执行default语句,打印出“无效的天数输入”。
运行结果:
在这里插入图片描述
default语句是Switch语句的一个重要组成部分,它增强了代码的健壮性和灵活性。尽管在某些简单的场景下可能被忽略,但在开发高质量、容错性强的软件时,添加default分支是一个很好的编程习惯。最好在编写Switch语句时考虑所有可能的情况,并利用default来处理那些意外或未知的输入。

default语句不一定要在最后

default语句不强制要求必须放在Switch语句中所有case语句的最后。C#编译器允许程序员将default标签放置在Switch结构的任何位置。

以下是一个例子:

int option = 3;
switch (option)
{case 1:Console.WriteLine("Option 1 selected.");break;default: // 这里default不是在最后Console.WriteLine("Default case executed.");break;case 2:Console.WriteLine("Option 2 selected.");break;case 3:Console.WriteLine("Option 3 selected.");break;
}

运行结果:
在这里插入图片描述

尽管允许灵活放置default,但为了代码的可读性,推荐将default放在最后一个位置,作为所有其他case都不匹配时的最终处理逻辑。

模式匹配

前面提到过,从C# 7.0开始,switch语句支持模式匹配,这意味着你不仅可以比较变量的值,还可以直接解构对象或检查变量是否符合某种模式。这大大增强了switch的表达能力。

class Program
{// 定义形状基类public abstract class Shape{}// 定义圆形类public class Circle : Shape{public double Radius { get; set; }public Circle(double radius){Radius = radius;}}// 定义正方形类public class Square : Shape{public double Side { get; set; }public Square(double side){Side = side;}}// 定义矩形类public class Rectangle : Shape{public double Width { get; set; }public double Height { get; set; }public Rectangle(double width, double height){Width = width;Height = height;}}static void Main(){var shape = GetShape();switch (shape){case Circle c when c.Radius > 10:Console.WriteLine($"大圆,半径为 {c.Radius}");break;case Square s when s.Side > 10:Console.WriteLine($"大方形,边长为{s.Side}");break;case Rectangle r:Console.WriteLine($"矩形,宽度为 {r.Width} 高度为 {r.Height}");break;case null:Console.WriteLine("Shape 为空");break;default:Console.WriteLine("未知形状");break;}}// 获取随机形状的方法static Shape GetShape(){Random random = new Random();int shapeType = random.Next(1, 4); // 生成1到3之间的随机数switch (shapeType){case 1:return new Circle(random.Next(5, 20)); // 半径5到19的圆case 2:return new Square(random.Next(5, 20)); // 边长5到19的正方形case 3:return new Rectangle(random.Next(5, 20), random.Next(5, 20)); // 长宽5到19的矩形default:return null; // 实际上不会执行到这,只是为了完整性}}}

这个示例,首先定义了一个抽象基类Shape,以及继承自它的Circle、Square和Rectangle具体形状类。GetShape方法随机返回一个形状实例,用于演示switch语句中的模式匹配。

运行结果:
在这里插入图片描述

与C++的差异-case穿透(Fall-through)

C++允许Switch语句中的case标签不使用break语句,这会导致执行完一个case块后,控制流会“穿透”到下一个case块,直到遇到break或Switch结构结束。这种机制有时候用于执行多个case共有的代码块,但也很容易造成逻辑错误,因为开发者可能无意中忘记写break。

C#则采取了更为严格的策略,不允许Case穿透。一旦某个case没有显式的break、goto case或throw语句、return关键字,程序会直接报错。这种设计有助于减少因忘记写break而导致的错误,使得代码更易于理解和维护。

但在某种写法下,C#也是可以穿透的,在文章后面会讲解。

下一篇文章

C#的Switch语句3

这篇关于C#的Switch语句2(case后的值与模式匹配)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1077583

相关文章

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

C#下Newtonsoft.Json的具体使用

《C#下Newtonsoft.Json的具体使用》Newtonsoft.Json是一个非常流行的C#JSON序列化和反序列化库,它可以方便地将C#对象转换为JSON格式,或者将JSON数据解析为C#对... 目录安装 Newtonsoft.json基本用法1. 序列化 C# 对象为 JSON2. 反序列化

C#文件复制异常:"未能找到文件"的解决方案与预防措施

《C#文件复制异常:未能找到文件的解决方案与预防措施》在C#开发中,文件操作是基础中的基础,但有时最基础的File.Copy()方法也会抛出令人困惑的异常,当targetFilePath设置为D:2... 目录一个看似简单的文件操作问题问题重现与错误分析错误代码示例错误信息根本原因分析全面解决方案1. 确保

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图

MySQL中REPLACE函数与语句举例详解

《MySQL中REPLACE函数与语句举例详解》在MySQL中REPLACE函数是一个用于处理字符串的强大工具,它的主要功能是替换字符串中的某些子字符串,:本文主要介绍MySQL中REPLACE函... 目录一、REPLACE()函数语法:参数说明:功能说明:示例:二、REPLACE INTO语句语法:参数

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅