0

0

C#的when关键字在catch中怎么用?如何条件捕获异常?

月夜之吻

月夜之吻

发布时间:2025-08-04 08:23:01

|

344人浏览过

|

来源于php中文网

原创

c# 中 when 关键字用于在 catch 块中添加条件,实现条件性异常捕获。1. 当异常类型匹配且 when 后的布尔条件为真时,catch 块才执行;2. 可基于异常属性(如 filename、message)或外部状态(如静态变量)进行判断;3. 支持通过 && 或 || 组合多个条件以实现复杂筛选;4. 条件评估发生在异常类型匹配后,性能影响通常较小,但应避免在条件中执行耗时操作;5. 相比传统 try-catch 和多 catch 块,when 提供更精细、简洁的异常过滤机制,提升代码可读性和维护性。该机制通过异常过滤器实现,使异常处理更灵活精准。

C#的when关键字在catch中怎么用?如何条件捕获异常?

C# 中

when
关键字允许你在
catch
块中添加一个条件,只有当条件为真时,该
catch
块才会执行。这实现了条件性异常捕获,使得异常处理更加精细和灵活。

解决方案:

使用

when
关键字,你可以根据异常的属性或其他上下文信息来决定是否处理该异常。 它的基本语法如下:

try
{
  // 可能抛出异常的代码
}
catch (SpecificExceptionType ex) when (condition)
{
  // 当异常类型为 SpecificExceptionType 且 condition 为真时执行
  // 处理异常的代码
}
catch (AnotherExceptionType ex)
{
  // 处理 AnotherExceptionType 异常的代码
}
catch (Exception ex)
{
  // 处理其他类型异常的代码
}

condition
可以是任何返回布尔值的表达式。 例如,你可以根据异常消息的内容、异常的自定义属性或者应用程序的当前状态来决定是否捕获异常。

举个例子,假设你正在处理文件操作,并且希望仅当文件名包含特定字符串时才捕获

IOException

try
{
  // 文件操作代码
  string filePath = "important_data.txt";
  if (!File.Exists(filePath))
  {
    throw new FileNotFoundException("文件未找到", filePath);
  }

  using (StreamReader reader = new StreamReader(filePath))
  {
    string content = reader.ReadToEnd();
    Console.WriteLine(content);
  }

}
catch (FileNotFoundException ex) when (ex.FileName.Contains("important"))
{
  Console.WriteLine($"重要文件未找到:{ex.FileName}");
  // 特定于重要文件的处理逻辑
}
catch (FileNotFoundException ex)
{
  Console.WriteLine($"文件未找到:{ex.FileName}");
  // 其他文件未找到的处理逻辑
}
catch (IOException ex)
{
  Console.WriteLine($"IO 异常:{ex.Message}");
}
catch (Exception ex)
{
  Console.WriteLine($"发生异常:{ex.Message}");
}

在这个例子中,第一个

catch
块仅在
FileNotFoundException
FileName
属性包含 "important" 时才会被执行。 否则,第二个
catch
块会处理所有其他
FileNotFoundException
异常。

使用

when
子句可以避免在
catch
块中编写复杂的
if
语句,从而使代码更简洁易懂。 此外,它允许你更精确地控制异常处理流程,只处理那些你真正需要处理的异常。

when
关键字不仅仅局限于检查异常对象的属性。 你可以使用任何可以访问的变量或方法来创建条件。 比如,你可以检查一个全局变量的状态,或者调用一个函数来确定是否应该处理异常。

private static bool _isCriticalError = false;

public static void SetCriticalError(bool value)
{
  _isCriticalError = value;
}

public static void DoSomething()
{
  try
  {
    // 一些代码
    throw new Exception("发生了错误");
  }
  catch (Exception ex) when (_isCriticalError)
  {
    // 仅当 _isCriticalError 为 true 时才处理异常
    Console.WriteLine("关键错误发生:" + ex.Message);
  }
  catch (Exception ex)
  {
    Console.WriteLine("其他错误发生:" + ex.Message);
  }
}

在这个例子中,只有当

_isCriticalError
变量为
true
时,第一个
catch
块才会执行。 这提供了一种基于应用程序状态来动态控制异常处理的方式。

如何处理多个
when
条件?

虽然不能直接在一个

catch
块中使用多个
when
子句,但你可以通过在
when
子句中使用复杂的布尔表达式来实现类似的效果。 你可以使用
&&
(AND) 和
||
(OR) 运算符来组合多个条件。

Detect GPT
Detect GPT

一个Chrome插件,检测您浏览的页面是否包含人工智能生成的内容

下载

例如:

try
{
  // 一些代码
  throw new ArgumentException("参数无效", "myParam");
}
catch (ArgumentException ex) when (ex.ParamName == "myParam" && ex.Message.Contains("无效"))
{
  // 仅当 ParamName 为 "myParam" 且 Message 包含 "无效" 时才处理
  Console.WriteLine("参数 'myParam' 无效:" + ex.Message);
}
catch (ArgumentException ex)
{
  Console.WriteLine("参数异常:" + ex.Message);
}

在这个例子中,只有当

ArgumentException
ParamName
属性为 "myParam" 并且
Message
属性包含 "无效" 时,第一个
catch
块才会被执行。 这允许你根据多个条件来精确地过滤异常。

when
子句的性能影响是什么?

when
子句的性能影响通常很小,但在某些情况下可能会有所不同。 当抛出异常时,CLR 会按照代码中出现的顺序评估
catch
块。 对于每个
catch
块,CLR 会首先检查异常类型是否匹配。 如果类型匹配,并且存在
when
子句,CLR 才会评估
when
子句中的条件。

如果

when
子句中的条件很复杂,或者涉及到大量的计算,那么评估
when
子句的开销可能会变得明显。 但是,在大多数情况下,
when
子句的开销可以忽略不计。

为了最大限度地减少

when
子句的性能影响,应该尽量保持条件简单高效。 避免在
when
子句中执行耗时的操作,例如数据库查询或复杂的字符串操作。 如果需要执行这些操作,最好在
try
块中完成,并将结果存储在一个变量中,然后在
when
子句中使用该变量。

when
关键字与其他异常处理方式的比较?

与其他异常处理方式相比,

when
关键字提供了一种更精细和灵活的异常处理机制。

  • 传统的

    try-catch
    块: 传统的
    try-catch
    块只能根据异常类型来过滤异常。
    when
    关键字允许你根据异常的属性或其他上下文信息来进一步过滤异常。

  • 多个

    catch
    块: 你可以使用多个
    catch
    块来处理不同类型的异常。 但是,如果你需要根据相同的异常类型但不同的条件来处理异常,那么使用
    when
    关键字会更加简洁和易于维护。

  • Exception filters
    (异常过滤器):
    when
    关键字也被称为异常过滤器。 它允许你编写一个表达式,该表达式确定是否应该处理异常。 如果表达式返回
    true
    ,则处理异常;否则,异常会继续向上冒泡。

总的来说,

when
关键字提供了一种强大的异常处理机制,可以帮助你编写更健壮和可维护的代码。 通过使用
when
关键字,你可以更精确地控制异常处理流程,只处理那些你真正需要处理的异常。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1468

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

229

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

85

2025.10.17

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

754

2023.08.22

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

78

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

96

2025.09.18

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

209

2023.09.04

Java JVM 原理与性能调优实战
Java JVM 原理与性能调优实战

本专题系统讲解 Java 虚拟机(JVM)的核心工作原理与性能调优方法,包括 JVM 内存结构、对象创建与回收流程、垃圾回收器(Serial、CMS、G1、ZGC)对比分析、常见内存泄漏与性能瓶颈排查,以及 JVM 参数调优与监控工具(jstat、jmap、jvisualvm)的实战使用。通过真实案例,帮助学习者掌握 Java 应用在生产环境中的性能分析与优化能力。

19

2026.01.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Django 教程
Django 教程

共28课时 | 3.3万人学习

MySQL 教程
MySQL 教程

共48课时 | 1.8万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号