C#学习笔记 - C#基础知识 - C#从入门到放弃 - C# 处理程序异常相关技术

更多C#基础知识点可查看:C#学习笔记 - C#基础知识 - C#从入门到放弃

第11节 处理程序异常相关技术

三种异常处理语句:
try...catch //捕获异常
try...finally //清除异常
try...catch...finally //处理所有异常

11.1 捕获异常

try…catch语句:
try...catch语句是最常见的异常处理技术。它允许我们在可能引发异常的代码块中捕获和处理异常。try块用于放置可能引发异常的代码,而catch块用于捕获和处理特定类型的异常
语法示例:

try
{
   
    // 可能引发异常的代码
    // ...
}
catch (ExceptionType1 ex)
{
   
    // 处理异常类型1
}
catch (ExceptionType2 ex)
{
   
    // 处理异常类型2
}

【代码示例】

            //利用try...catch语句来捕获数组的越界问题
            int[] intArray = {
    0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };

            try
            {
   
                for (int i = 0; i <= intArray.Length; i++)
                    Console.Write(intArray[i] + " ");
            }
            catch(Exception myex)
            {
   
                Console.WriteLine("\n程序出现异常:"+myex.Message);
                //Console.WriteLine(myex.Message.ToString());

            }
            Console.ReadKey();

运行程序:

0 2 4 6 8 10 12 14 16 18 20
程序出现异常:索引超出了数组界限。

11.2 清除、处理所有异常

finally块:
finally块用于指定无论是否发生异常,都要执行的清理代码。无论是否发生异常,finally块中的代码都会被执行。通常情况下,在finally块中进行释放占用资源或确保某些操作完成的操作。
语法示例:

try
{
   
    // 可能引发异常的代码
}
finally
{
   
    // 清理代码
}

此语法可以处理异常,但是无法看见任何异常信息,所以可以结合catch语句,组合成以下语法:

try
{
   
    // 可能引发异常的代码
}
catch (Exception ex)
{
   
    // 处理异常
}
finally
{
   
    // 清理代码
}

【代码示例】

            int[] intArray = {
    0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
            try
            {
   
                for (int i = 0; i < intArray.Length; i++)
                {
   
                    int temp = 720 / intArray[i];
                    Console.WriteLine("720÷{0}={1}", intArray[i], temp);
                }
            }
            catch(Exception myex)
            {
   
                Console.WriteLine(myex.Message);
            }
            finally
            {
   
                Console.WriteLine("无论是否发生异常,此finally语句块中代码都会被执行。");
            }

            Console.ReadKey();

运行程序:

尝试除以零。
无论是否发生异常,此finally语句块中代码都会被执行。

11.3 引发异常

throw语句:
throw语句用于手动引发异常。可以使用throw语句在代码中显式引发异常对于创建自定义异常或重新引发现有异常时非常有用。

【示例】
定义一个将字符串转换为整数的私有静态方法ConvertStringToInt;它含有一个字符串类型参数,返回一个整数,然后使用方法将一个不能转换成整数的字符串转换成整数,从而引发异常
private static int ConvertStringToInt(String mystr)

    class Program
    {
   
        private static int ConvertStringToInt(string mystr)
        {
   
            int outnum = 0;
            try
            {
   
                outnum = Convert.ToInt32(mystr);
                return outnum;
            }
            catch
            {
   
                throw new FormatException("Eorr:格式转换 不正确");
            }
        }
        static void Main(string[] args)
        {
   
            //string mystr = "123";         //123
            string mystr = "hao123";        //Eorr:格式转换 不正确
            try
            {
   
                int myint;
                myint = Program.ConvertStringToInt(mystr);
                Console.WriteLine(myint);
            }
            catch(FormatException exf)
            {
   
                Console.WriteLine(exf.Message);
            }

            Console.ReadKey();
        }
    }

11.4 预定义异常类

在C#中,有许多预定义的异常类,它们分别用于表示不同类型的异常情况。以下是一些常见的预定义异常类的简要介绍:

异常类 说明
Exception Exception是所有异常类的基类,它表示通用的异常情况。一般情况下,我们不直接使用Exception类,而是使用它的子类。
SystemException SystemException是Exception的子类,它代表由.NET框架或CLR引发的异常。例如,NullReferenceException和DivideByZeroException都是SystemException的子类。
ApplicationException ApplicationException是Exception的子类,它代表由应用程序代码引发的异常。通常,我们可以通过自定义的方式来创建派生自ApplicationException的自定义异常类。
ArgumentException ArgumentException代表参数异常,表示一个或多个方法参数不符合预期。它有一些常见的子类,如ArgumentNullException(参数为null),ArgumentOutOfRangeException(参数超出有效范围)等。
InvalidOperationException InvalidOperationException表示在对象的当前状态下,操作是无效的或不合理的异常。这个异常通常在对象的状态不允许执行某个操作时引发。
IndexOutOfRangeException IndexOutOfRangeException表示索引超出范围的异常,通常在数组或集合访问时发生。
NullReferenceException NullReferenceException表示空引用异常,当尝试通过对null引用进行成员访问、方法调用或属性访问时,会引发此异常。
DivideByZeroException DivideByZeroException表示除以零的异常,当对一个数字类型进行除法运算时,除数为零时会引发此异常。

【部分异常类示例】
1、ArgumentException

        static int DivideByTwo(int num)
        {
   
            if (num % 2 == 1)
                throw new ArgumentException("此处必须为偶数", "num");
            return num / 2;
        }
        static void Main(string[] args)
        {
   
            //ArgumentException异常
            try
            {
   
                Console.WriteLine(DivideByTwo(9));
            }
            catch(ArgumentException exa1)
            {
   
                //Console.WriteLine("9不能被2整除");
                Console.WriteLine(exa1.Message);
            }
            
            Console.ReadKey();
        }

运行结果:

此处必须为偶数
参数名: num

2、InvalidCastException

            //2、InvalidCastException 异常
            bool myBool = true;
            try
            {
   
                char myChar = Convert.ToChar(myBool);
            }
            catch(InvalidCastException exi)
            {
   
                Console.WriteLine(exi.Message);
            }

运行程序:

从“Boolean”到“Char”的强制转换无效。

3、ArrayTypeMismatchException

            //ArrayTypeMismatchException 异常
            string[] myStr = {
    "Cat", "Dog", "Pig", "Dock" };
            object[] myObj = myStr;
            try
            {
   
                foreach (object outobj in myObj)
                {
   
                    Console.Write(outobj + "  ");
                    Console.WriteLine(outobj.GetType());
                    myObj[1] = 13;
                }
            }
            catch (ArrayTypeMismatchException exa2)
            {
   
                Console.WriteLine(exa2.Message);
            }

运行程序:

Cat  System.String
尝试访问类型与数组不兼容的元素。

4、OverflowException

            //OverflowException 
            try
            {
   
                byte myByte = Convert.ToByte(Console.ReadLine());
                Console.WriteLine(myByte);
            }
            catch(OverflowException exo)
            {
   
                Console.WriteLine(exo.Message);
            }

运行程序:

//输入范围内数值
123
123

//输入超出范围数值
266
值对于无符号的字节太大或太小。

11.5 自定义异常类

在C#中,可以通过继承预定义的异常类来创建自定义异常类,以表示特定的异常情况。自定义异常类可以提供更多的信息和上下文,以便更好地定位和处理异常。

1、继承预定义的异常类:
要创建自定义异常类,首先要选择一个适合的预定义异常类作为基类。通常,如果可以找到与自定义异常类型相关的现有预定义异常类,那么最好继承那个异常类。基于自定义异常的性质和用途,可以选择继承的异常类,如ExceptionApplicationException等。

2、添加构造函数:
在自定义异常类中,我们应该添加合适的构造函数来初始化异常对象。构造函数可以接受参数以提供额外的信息,例如错误消息、内部异常和其他上下文数据。通常,自定义异常类的构造函数应该调用基类的构造函数,以便为基类异常提供必要的信息。

3、添加额外的属性和方法:
除了继承自基类的属性和方法之外,我们也可以为自定义异常类添加自己的属性和方法,用于提供更多的异常信息或定制化的异常处理逻辑。这些额外的属性和方法可以根据具体需求来设计。

【自定义异常类示例】
1、只定义自定义异常类

    class MyException : Exception
    {
   
    }
    class Program
    {
   
        static void Main(string[] args)
        {
   
            try
            {
   
                Console.WriteLine("此语句在引发异常前输出。");
                throw new MyException();
                Console.WriteLine("由于引发了异常,此语句不会被输出。");
            }
            catch(MyException exm)
            {
   
               Console.WriteLine(exm.Message);               
               Console.WriteLine("自定义异常(由程饱饱定义):输出此语句说明引发异常。");
            }
            Console.ReadKey();
        }
    }

运行程序:

此语句在引发异常前输出。
引发类型为“自定义异常类.MyException”的异常。
自定义异常(由程饱饱定义):输出此语句说明引发异常。

2、在内中定义方法

    class MyException : Exception
    {
   
        public MyException(string message):base(message)
        {
   
        }
    }
    class Program
    {
   
        static void Main(string[] args)
        {
   
            try
            {
   
                Console.WriteLine("此语句在引发异常前输出。");
                string myStr = "自定义异常(由程饱饱定义):输出此语句说明引发异常。";
                throw new MyException(myStr);
                Console.WriteLine("由于引发了异常,此语句不会被输出。");
            }
            catch(MyException exm)
            {
   
                Console.WriteLine(exm.Message);
                //Console.WriteLine("自定义异常(由程饱饱定义):输出此语句说明引发异常。");
            }
            
            Console.ReadKey();
        }
    }

运行程序:

此语句在引发异常前输出。
引发类型为“自定义异常类.MyException”的异常。
自定义异常(由程饱饱定义):输出此语句说明引发异常。

11.6 异常的综合运用

1、输入一个数(int),求该数的倒数
2、根据用户输入的内容的不同产生相应异常提示:
① 除零异常 - 0
② 溢出异常 - 2^32
③ 转换异常 - string->int
④ 其他未知异常
【示例】

        static void Main(string[] args)
        {
   
            Console.WriteLine("请输入一个整数:");
            try
            {
   
                int myInt = int.Parse(Console.ReadLine());
                double myDouble = 1.0 / myInt;
                Console.WriteLine("该数的倒数是:"+myDouble);
            }
            catch(DivideByZeroException)
            {
   
                Console.WriteLine("产生除零异常");
            }
            catch (OverflowException)
            {
   
                Console.WriteLine("产生溢出异常");
            }
            catch (FormatException)
            {
   
                Console.WriteLine("产生转换异常");
            }
            catch (Exception)
            {
   
                Console.WriteLine("产生其他异常");
            }

            Console.ReadKey();
        }

运行结果:

请输入一个整数:
0
该数的倒数是:∞
请输入一个整数:
4294967297
产生溢出异常
请输入一个整数:
hao123
产生转换异常
请输入一个整数:
5
该数的倒数是:0.2

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2023-12-28 21:38:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-28 21:38:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-28 21:38:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-28 21:38:02       18 阅读

热门阅读

  1. odoo17核心概念view4——view.js

    2023-12-28 21:38:02       39 阅读
  2. vue大屏-列表自动滚动vue-seamless-scroll

    2023-12-28 21:38:02       39 阅读
  3. redis开启密码验证

    2023-12-28 21:38:02       31 阅读
  4. 在next13当中使用centrifuge5.0.1进行websocket请求

    2023-12-28 21:38:02       35 阅读
  5. Linux 命令

    2023-12-28 21:38:02       29 阅读
  6. 常见的hooks

    2023-12-28 21:38:02       34 阅读