C#开发——如何捕获异常和抛出异常

news/2025/2/25 18:22:01

一、捕获异常

        在 C#中,可以通过“try-catch”块捕获异常,并通过“is”关键字或“as”关键字来判断异常的具体类型。以下是几种常见的方法来判断异常类型:

方法 1:使用“catch”块直接捕获特定类型的异常

        在 C#中,可以在“catch”块中直接指定要捕获的异常类型。这种方式可以在捕获异常时直接区分不同类型的异常。

try
{
    // 可能抛出异常的代码
    int result = 10 / 0;
}
catch (DivideByZeroException ex) // 捕获特定类型的异常
{
    Console.WriteLine("捕获到除零异常: " + ex.Message);
}
catch (Exception ex) // 捕获所有其他类型的异常
{
    Console.WriteLine("捕获到其他异常: " + ex.Message);
}

方法 2:使用“is”关键字判断异常类型

        如果捕获到的异常是“Exception”类型,可以在“catch”块中使用“is“关键字来判断异常的具体类型。

try
{
    // 可能抛出异常的代码
    throw new ArgumentException("这是一个参数异常");
}
catch (Exception ex)
{
    if (ex is ArgumentException)
    {
        Console.WriteLine("捕获到 ArgumentException: " + ex.Message);
    }
    else if (ex is InvalidOperationException)
    {
        Console.WriteLine("捕获到 InvalidOperationException: " + ex.Message);
    }
    else
    {
        Console.WriteLine("捕获到其他类型的异常: " + ex.Message);
    }
}

方法 3:使用“as”关键字判断异常类型“as”关键字

可以将异常对象转换为特定的类型,如果转换成功,则说明异常是该类型或其派生类型。

try
{
    // 可能抛出异常的代码
    throw new FileNotFoundException("文件未找到");
}
catch (Exception ex)
{
    FileNotFoundException fileEx = ex as FileNotFoundException;
    if (fileEx != null)
    {
        Console.WriteLine("捕获到 FileNotFoundException: " + fileEx.Message);
    }
    else
    {
        Console.WriteLine("捕获到其他类型的异常: " + ex.Message);
    }
}

方法 4:使用“GetType()”方法获取异常类型

可以通过“GetType()”方法获取异常的类型信息。

try
{
    // 可能抛出异常的代码
    throw new NullReferenceException("引用为空");
}
catch (Exception ex)
{
    Console.WriteLine("捕获到的异常类型是: " + ex.GetType().Name);
    Console.WriteLine("异常信息: " + ex.Message);
}

方法 5:使用“when”关键字(C# 6.0+)

        C# 6.0 引入了“when”关键字,可以在“catch”块中添加条件,从而更灵活地捕获特定类型的异常。

try
{
    // 可能抛出异常的代码
    throw new Exception("这是一个普通异常");
}
catch (Exception ex) when (ex is ArgumentException)
{
    Console.WriteLine("捕获到 ArgumentException: " + ex.Message);
}
catch (Exception ex) when (ex is InvalidOperationException)
{
    Console.WriteLine("捕获到 InvalidOperationException: " + ex.Message);
}
catch (Exception ex)
{
    Console.WriteLine("捕获到其他类型的异常: " + ex.Message);
}

总结

• 如果你希望直接捕获特定类型的异常,推荐使用方法 1(直接在   catch   块中指定异常类型)。

• 如果你需要在捕获到异常后进一步判断类型,可以使用 “is”、“as” 或 “GetType()” 方法。

• 如果你使用的是 C# 6.0 或更高版本,“when   关键字可以提供更灵活的异常捕获逻辑。

根据你的具体需求选择合适的方法即可!

二、抛出异常

        在C#中,抛出异常是一种处理程序运行时错误或异常情况的机制。你可以使用  throw  关键字来抛出自定义异常或预定义的异常类型。以下是抛出异常的几种常见方式:

1、抛出预定义的异常

C# 提供了许多预定义的异常类型,如  ArgumentException  、  ArgumentNullException  、  InvalidOperationException  等。你可以直接使用这些异常类型来抛出异常。

public void Divide(int a, int b)
{
    if (b == 0)
    {
        throw new DivideByZeroException("除数不能为零!");
    }

    Console.WriteLine(a / b);
}

在这个例子中,如果  b  为0,程序会抛出一个  DivideByZeroException  ,并附带一条错误信息。

2. 抛出自定义异常

        你可以创建自己的异常类,继承自  Exception  或其子类。自定义异常类可以包含额外的属性和方法,以提供更多上下文信息。

public class MyCustomException : Exception
{
    public MyCustomException(string message) : base(message)
    {
    }

    public MyCustomException(string message, Exception innerException) : base(message, innerException)
    {
    }
}

public void CheckAge(int age)
{
    if (age < 18)
    {
        throw new MyCustomException("年龄必须大于或等于18岁!");
    }

    Console.WriteLine("年龄验证通过!");
}

        在这个例子中,  MyCustomException  是一个自定义异常类,  CheckAge  方法会在年龄小于18时抛出这个自定义异常。

3、重新抛出异常

        在捕获异常后,你可能需要对异常进行处理,然后重新抛出它,或者抛出一个新的异常。这可以通过  throw  关键字实现。

try
{
    // 模拟一个异常
    throw new InvalidOperationException("原始异常");
}
catch (Exception ex)
{
    Console.WriteLine("捕获到异常:" + ex.Message);

    // 重新抛出原始异常
    throw;

    // 或者抛出一个新的异常
    // throw new ApplicationException("新的异常", ex);
}

在这个例子中:

使用  throw;重新抛出捕获到的原始异常。

使用  throw new Exception(...);  可以抛出一个新的异常,并将原始异常作为内部异常传递。

4、抛出异常时附带堆栈信息

当你抛出一个新的异常时,可以通过  innerException  参数将原始异常的堆栈信息保留下来。这有助于调试和错误追踪。

try
{
    throw new InvalidOperationException("原始异常");
}
catch (Exception ex)
{
    throw new ApplicationException("新的异常", ex);
}

在这个例子中,  ApplicationException  的构造函数中传递了原始异常  ex  作为  innerException  ,这样可以保留完整的堆栈跟踪信息。

5、使用  ArgumentNullException  和  ArgumentException

在方法中检查参数时,如果参数不符合要求,通常会抛出  ArgumentNullException  或  ArgumentException  。

public void PrintName(string name)
{
    if (name == null)
    {
        throw new ArgumentNullException(nameof(name), "参数不能为空!");
    }

    if (string.IsNullOrWhiteSpace(name))
    {
        throw new ArgumentException("参数不能为空或空白!", nameof(name));
    }

    Console.WriteLine(name);
}

总结

在C#中,抛出异常是一种重要的错误处理机制。你可以:

1、抛出预定义的异常(如  ArgumentException  、  InvalidOperationException  等)。

2、创建并抛出自定义异常。

3、在捕获异常后重新抛出或抛出新的异常。

4、通过  innerException  保留原始异常的堆栈信息。

合理使用异常机制可以提高代码的健壮性和可维护性。

三、常见的异常类

        在C#中,.NET框架提供了许多预定义的异常类,用于处理各种运行时错误和异常情况。这些异常类都继承自  System.Exception  类。以下是一些常用的异常类及其用途:

1、系统级异常

这些异常通常由运行时环境抛出,表示程序运行时发生了严重错误。

System.Exception:所有异常的基类。通常不直接抛出,而是作为其他异常的基类。

System.SystemException:表示由.NET运行时环境抛出的系统级异常。

throw new Exception("未知错误");
throw new SystemException("系统级错误");

2、程序逻辑异常

这些异常通常由程序逻辑错误引起,例如无效的参数、非法操作等。

System.ArgumentException  :表示传递给方法的参数无效。

System.ArgumentNullException:表示传递给方法的参数为  null  。

System.ArgumentOutOfRangeException:表示参数的值超出了预期范围。

if (string.IsNullOrEmpty(name))
{
    throw new ArgumentException("参数不能为空!", nameof(name));
}

if (name == null)
{
    throw new ArgumentNullException(nameof(name), "参数不能为空!");
}

if (age < 0)
{
    throw new ArgumentOutOfRangeException(nameof(age), "年龄不能为负数!");
}

3、运行时异常

这些异常通常由运行时环境抛出,表示程序运行时发生了错误。

System.InvalidOperationException:表示在当前状态下无法执行操作。

System.NotSupportedException:表示尝试执行不支持的操作。

System.NotImplementedException:表示方法或操作尚未实现。

if (list.Count == 0)
{
    throw new InvalidOperationException("列表为空,无法执行操作!");
}

throw new NotSupportedException("此操作不支持!");

throw new NotImplementedException("此方法尚未实现!");

4、IO和资源异常

这些异常通常与文件、网络或其他资源操作有关。

System.IO.IOException:表示I/O操作失败。

System.IO.FileNotFoundException:示指定的文件未找到。

System.IO.DirectoryNotFoundException:表示指定的目录未找到。

throw new IOException("I/O操作失败!");

throw new FileNotFoundException("文件未找到!", "example.txt");

throw new DirectoryNotFoundException("目录未找到!");

5、线程和并发异常

这些异常通常与多线程或并发操作有关。

System.Threading.ThreadAbortException:表示线程被中止。

System.Threading.SynchronizationLockException:示在尝试进入同步块时发生错误。

throw new ThreadAbortException("线程被中止!");

throw new SynchronizationLockException("同步锁异常!");

6、 数据和格式异常

这些异常通常与数据格式或类型转换有关。

System.FormatException:表示字符串格式不正确。

System.InvalidCastException:表示尝试将对象强制转换为不兼容的类型。

System.OverflowException:表示算术运算超出数据类型的范围。

throw new FormatException("格式不正确!");

throw new InvalidCastException("类型转换失败!");

throw new OverflowException("数值溢出!");

7、网络和通信异常

这些异常通常与网络操作或通信失败有关。

System.Net.Sockets.SocketException:表示套接字操作失败。

System.Net.WebException:表示Web请求失败。

throw new SocketException("套接字操作失败!");

throw new WebException("Web请求失败!");

8、其他常见异常

System.DivideByZeroException:表示除数为零。

System.NullReferenceException:表示尝试访问  null  对象的成员。

System.ApplicationException: 表示应用程序级错误(较少使用)。

throw new DivideByZeroException("除数不能为零!");

throw new NullReferenceException("对象引用未设置为对象的实例!");

throw new ApplicationException("应用程序错误!");

总结

        这些异常类覆盖了大多数常见的错误场景。在实际开发中,选择合适的异常类可以更清晰地表达错误的性质,便于调试和维护。同时,合理使用异常机制可以提高程序的健壮性和用户体验。


http://www.niftyadmin.cn/n/5865824.html

相关文章

【react】进阶教程02

目录 一、深度性能优化 1. 列表渲染优化&#xff08;虚拟列表&#xff09; 2. 使用 Web Workers 处理 CPU 密集型任务 二、复杂状态管理场景 1. 全局状态分层&#xff08;Context useReducer&#xff09; 2. 异步状态管理中间件&#xff08;Redux Thunk&#xff09; 三、…

【NLP 37、激活函数 ③ relu激活函数】

—— 25.2.23 ReLU广泛应用于卷积神经网络&#xff08;CNN&#xff09;和全连接网络&#xff0c;尤其在图像分类&#xff08;如ImageNet&#xff09;、语音识别等领域表现优异。其高效性和非线性特性使其成为深度学习默认激活函数的首选 一、定义与数学表达式 ReLU&#xff0…

IDEA创建Spring配置文件Spring Config的方法

作为刚刚开始学Spring框架的小白&#xff0c;而且我也是刚刚学怎么用idea&#xff0c;不会简单的操作也是很正常的是吧。这个问题其实只是我傻傻的不懂&#xff0c;是个很简单的问题&#xff0c;我现在把它记录下来。 在idea创建maven项目后&#xff0c;我们在左边右键新建xml文…

[AI相关]问问DeepSeek如何基于Python,moviePy实现视频字幕功能

最多3个问题&#xff0c;必然命中目标 遇事不决先问问DeepSeek 我个人对Python和一些库&#xff0c;一些第三方工具都不是很了解的&#xff0c;所以&#xff0c; 问&#xff1a;”python videopy 能作什么"//不但英文写错了&#xff0c;中文应该都写错了。。。。 一如既…

作业day5

封装一个mystring类 拥有私有成员&#xff1a; char* p int len 需要让以下代码编译通过&#xff0c;并实现对应功能 mystring str "hello" mystring ptr; ptr.copy(str) ptr.append(str) ptr.show() 输出ptr代表的字符串 ptr.compare(str) 比较ptr和str是否一样 pt…

【关于seisimic unix中使用suedit指令无法保存问题】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、如何修改头文件二、出现的问题尝试解决使用ls显示文件属性使用chmod修改文件属性 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff…

【行业解决方案篇二】【当图神经网络成为“金融侦探”:DeepSeek反洗钱系统技术全解】

一、为什么传统反洗钱系统像“拿着渔网捞针”? 金融犯罪每年造成全球8万亿美元损失,而传统规则引擎存在三大致命伤: 规则滞后:依赖人工设定的固定阈值(如单日转账>50万触发警报),黑产通过“化整为零”轻松绕过关联缺失:仅分析单笔交易,无法识别多层嵌套的“资金迷…

20250223下载并制作RTX2080Ti显卡的显存的测试工具mats

20250223下载并制作RTX2080Ti显卡的显存的测试工具mats 2025/2/23 23:23 缘起&#xff1a;我使用X99的主板&#xff0c;使用二手的RTX2080Ti显卡【显存22GB版本&#xff0c;准备学习AI的】 但是半年后发现看大码率的视频容易花屏&#xff0c;最初以为是WIN10经常更换显卡/来回更…