当前位置: 首页 > article >正文

C# 异常处理全解析


.NET学习资料

.NET学习资料

.NET学习资料


在 C# 编程中,异常处理是一项至关重要的技术,它能够确保程序在面对各种意外情况时仍能稳定运行。本文将深入探讨 C# 异常处理的相关知识。

一、什么是异常

异常是程序在运行过程中发生的错误或意外情况。当程序执行遇到无法正常处理的状况时,就会抛出一个异常,以通知程序出现了问题。异常是一种特殊的事件,若不加以捕获和处理,程序可能会崩溃或意外终止。常见的异常类型有:

DivideByZeroException:当进行除法运算时,若除数为零,就会抛出此异常。

NullReferenceException:尝试访问空引用对象的成员或调用空引用对象的方法时,会引发该异常。

IndexOutOfRangeException:在访问数组、集合等具有索引的对象时,如果索引超出了有效范围,就会抛出此异常。

FileNotFoundException:当试图访问一个不存在的文件时,会出现这个异常。

二、为何需要异常处理

在程序编写过程中,错误的发生难以完全避免。例如,用户可能会输入不符合预期的数据,网络连接可能会突然中断,文件可能在运行时丢失等。倘若不对这些异常情况进行处理,程序就会直接崩溃,这将给用户带来极差的体验。通过异常处理,我们可以实现以下几点:

捕获异常:在检测到错误时,防止程序立即崩溃,使程序有机会进行后续处理。

处理异常:针对不同类型的异常,采取相应的措施,让程序能够继续运行,或者以友好的方式退出。

提供反馈:向用户展示有用的错误信息,这不仅有助于用户了解问题所在,也方便开发者进行调试和程序改进。

三、异常处理的关键字

C# 中异常处理主要借助以下关键字来实现:

try:用于包裹可能产生异常的代码块。在try块中执行的代码,一旦出现异常,就会被后续的catch块捕获。

catch:负责捕获try块中抛出的异常,并对其进行相应的处理。可以根据不同的异常类型,编写多个catch块来分别处理。

finally:无论try块中是否发生异常,finally块中的代码都会被执行。通常用于执行一些资源清理操作,比如关闭文件、释放数据库连接等。

throw:允许开发者主动抛出一个异常,以便在特定的业务逻辑下,通知程序出现了需要特殊处理的情况。

四、异常处理的基本结构

C# 异常处理的基本结构如下:

try
{
    // 可能产生异常的代码
}
catch (ExceptionType ex)
{
    // 对异常进行处理的代码
}
finally
{
    // 无论是否发生异常,都会执行的代码
}

在这个结构中:

try块包含了可能会引发异常的代码段。

catch块紧跟在try块之后,用于捕获并处理特定类型的异常。ExceptionType表示要捕获的异常类型,ex是一个异常对象,通过它可以获取异常的详细信息。

finally块是可选的,它里面的代码无论try块中是否发生异常,都会被执行。常用于执行一些必须执行的清理操作,确保资源的正确释放。

五、实例解析异常和异常处理

5.1 未处理异常的情况

using System;

class Program
{
    static void Main()
    {
        int a = 10;
        int b = 0;
        int result = a / b; // 除以零,抛出异常
        Console.WriteLine("结果是:" + result);
    }
}

在这段代码中,由于进行了除以零的操作,会抛出DivideByZeroException异常。由于没有对该异常进行处理,程序会直接崩溃,并输出异常信息:Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.

5.2 使用异常处理

using System;

class Program
{
    static void Main()
    {
        int a = 10;
        int b = 0;
        try
        {
            int result = a / b; // 可能引发异常的代码
            Console.WriteLine("结果是:" + result);
        }
        catch (DivideByZeroException ex)
        {
            Console.WriteLine("发生错误:不能除以零!");
            // 可以根据需要输出异常信息
            // Console.WriteLine(ex.Message);
        }
    }
}

在这个例子中,try块包含了可能发生异常的代码int result = a / b;。当b为零时,会抛出DivideByZeroException异常。catch块捕获到该异常,并执行其中的代码,输出提示信息发生错误:不能除以零!。此时程序不会崩溃,可以继续执行后续的代码。

5.3 使用finally块

using System;
using System.IO;

class Program
{
    static void Main()
    {
        StreamReader sr = null;
        try
        {
            sr = new StreamReader("test.txt");
            string content = sr.ReadToEnd();
            Console.WriteLine(content);
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine("文件未找到!");
        }
        finally
        {
            // 无论是否发生异常,都要关闭文件
            if (sr!= null)
            {
                sr.Close();
                Console.WriteLine("文件已关闭。");
            }
        }
    }
}

在这段代码中,try块尝试读取文件test.txt。如果文件不存在,会抛出FileNotFoundException异常,并被catch块捕获。finally块中的代码会在try和catch块执行完后执行,用于关闭文件等清理操作。即使发生异常,finally块仍然会执行,确保文件资源被正确释放。

5.4 使用throw关键字

using System;

class Program
{
    static void Main()
    {
        try
        {
            CheckAge(15);
        }
        catch (Exception ex)
        {
            Console.WriteLine("错误:" + ex.Message);
        }
    }

    static void CheckAge(int age)
    {
        if (age < 18)
        {
            throw new Exception("未成年人禁止入内!");
        }
        else
        {
            Console.WriteLine("欢迎光临!");
        }
    }
}

在CheckAge方法中,如果age小于 18,就会使用throw关键字主动抛出一个Exception异常。在Main方法中,调用CheckAge(15)时,由于age为 15,会抛出异常。catch块捕获到该异常,并输出错误信息错误:未成年人禁止入内!

六、自定义异常

在某些情况下,C# 内置的异常类型可能无法满足特定的业务需求。此时,我们可以自定义异常类型。自定义异常通常继承自Exception类或它的子类。例如:

using System;

// 自定义异常类
class MyCustomException : Exception
{
    public MyCustomException(string message) : base(message)
    {
    }
}

class Program
{
    static void Main()
    {
        try
        {
            DoSomething();
        }
        catch (MyCustomException ex)
        {
            Console.WriteLine("自定义异常:" + ex.Message);
        }
    }

    static void DoSomething()
    {
        // 模拟某种业务逻辑,满足特定条件时抛出自定义异常
        if (DateTime.Now.Hour < 12)
        {
            throw new MyCustomException("上午时间不允许执行此操作!");
        }
        else
        {
            Console.WriteLine("操作成功执行!");
        }
    }
}

在这个例子中,我们定义了一个MyCustomException类,它继承自Exception类。在DoSomething方法中,根据当前时间是否在上午来决定是否抛出自定义异常。在Main方法中,通过catch块捕获并处理这个自定义异常。

通过以上对 C# 异常处理的全面介绍,希望能帮助开发者更好地掌握这一重要的编程技术,编写出更加健壮、稳定的程序。


http://www.kler.cn/a/535472.html

相关文章:

  • arm 下 多线程访问同一变量 ,使用原子操作 性能差问题
  • 基于MODIS/Landsat/Sentinel/国产卫星遥感数据与DSSAT作物模型同化的作物产量估算
  • 基于docker搭建Kafka集群,使用KRaft方式搭建,摒弃Zookeeper
  • 深入理解 YUV Planar 和色度二次采样 —— 视频处理的核心技术
  • 深入理解和使用定时线程池ScheduledThreadPoolExecutor
  • C++17新特性:结构化绑定
  • 3.【BUUCTF】XSS-Lab1
  • python 小游戏:扫雷
  • JVM与Java体系结构
  • 【贪心算法篇】:“贪心”之旅--算法练习题中的智慧与策略(四)
  • VUE小技能:通过 Prop 向子组件传递数据
  • 【游戏设计】游戏中的玩法与规则
  • 虹科波形小课堂 | 三分钟掌握车辆相对压缩测试!不拆发动机、不测缸压就能判断故障缸!
  • 深度学习-103-RAG技术之通过分块技术提升RAG的效果
  • 从零开始:OpenCV 图像处理快速入门教程
  • 1.8 组合模式(Composite Pattern)
  • Three.js 实现海面效果
  • Java面试题及答案整理( 2023年 6 月最新版,持续更新)
  • Java面试知识点总结
  • Monorepo保姆级教程
  • SpringCloud详细讲解
  • ubuntu linux 内核锁定
  • WindowsServer搭建内网Gitea【中文更方便使用】
  • 打造高效Facebook矩阵账号运营策略
  • 【码道初阶】Floyd判圈法个人总结:快慢双指针判断环形列表(适用Leetcode142)
  • Java全栈项目-校园闲置教室查询系统