C#异常总结

定义

程序中的运行时错误,它违反一个系统约束或应用程序约束,或出现了在正常操作时未预料的情形。

Try语句

指明被异常保护的代码块,并提供代码以处理异常。try由三部分组成:try…catch finally.

try:包含正被异常保护的代码

catch:含有一个或多个catch子句,这些是处理异常的代码块,也叫做异常处理程序

finally:含有在所有情况下都要被执行的代码,无论有没有异常发生
在这里插入图片描述

异常类

BCL定义了许多类,每一个类代表一个指定的异常类型,当一个异常发生时,CLR:

  • 创建该类型的异常对象
  • 寻找适当的catch子句以处理 它

所有异常类都从根本上派生自system.exception类,异常继承层次如下
在这里插入图片描述

异常类类型包括:基类:System.Exception;系统级异常:System.SystemException;应用程序级异常:System.ApplicationException。

(1).由System.SystemException派生的异常类型:

System.AccessViolationException在试图读写受保护内存时引发的异常。
System.ArgumentException在向方法提供的其中一个参数无效时引发的异常。
System.Collections.Generic.KeyNotFoundException指定用于访问集合中元素的键与集合中的任何键都不匹配时所引发的异常。
System.IndexOutOfRangeException访问数组时,因元素索引超出数组边界而引发的异常。
System.InvalidCastException因无效类型转换或显示转换引发的异常。
System.InvalidOperationException当方法调用对于对象的当前状态无效时引发的异常。
System.InvalidProgramException当程序包含无效Microsoft中间语言(MSIL)或元数据时引发的异常,这通常表示生成程序的编译器中有bug。
System.IO.IOException发生I/O错误时引发的异常。
System.NotImplementedException在无法实现请求的方法或操作时引发的异常。
System.NullReferenceException尝试对空对象引用进行操作时引发的异常。
System.OutOfMemoryException没有足够的内存继续执行程序时引发的异常。
System.StackOverflowException挂起的方法调用过多而导致执行堆栈溢出时引发的异常。

(2).由System.ArgumentException派生的异常类型:

System.ArgumentNullException当将空引用传递给不接受它作为有效参数的方法时引发的异常。
System.ArgumentOutOfRangeException当参数值超出调用的方法所定义的允许取值范围时引发的异常。

(3).由System.ArithmeticException派生的异常类型:

System.DivideByZeroException试图用零除整数值或十进制数值时引发的异常。
System.NotFiniteNumberException当浮点值为正无穷大、负无穷大或非数字(NaN)时引发的异常。
System.OverflowException在选中的上下文中所进行的算数运算、类型转换或转换操作导致溢出时引发的异常。

(4).由System.IOException派生的异常类型:

System.IO.DirectoryNotFoundException当找不到文件或目录的一部分时所引发的异常。
System.IO.DriveNotFoundException当尝试访问的驱动器或共享不可用时引发的异常。
System.IO.EndOfStreamException读操作试图超出流的末尾时引发的异常。
System.IO.FileLoadException当找到托管程序却不能加载它时引发的异常。
System.IO.FileNotFoundException试图访问磁盘上不存在的文件失败时引发的异常。
System.IO.PathTooLongException当路径名或文件名超过系统定义的最大长度时引发的异常。

(5).其他常用异常类型:

ArrayTypeMismatchException试图在数组中存储错误类型的对象。
BadImageFormatException图形的格式错误。
DivideByZeroException除零异常。
DllNotFoundException找不到引用的dll。
FormatException参数格式错误。
MethodAccessException试图访问私有或者受保护的方法。
MissingMemberException访问一个无效版本的dll。
NotSupportedException调用的方法在类中没有实现。
PlatformNotSupportedException平台不支持某个特定属性时抛出该错误。

创建用户自定义异常

自定义的异常类派生自ApplicationException类

    class Program
    {
        static void Main(string[] args)
        {
            //用户自定义的异常类是派生自ApplicationException类
            Temperture temp = new Temperture();
            try
            {
                temp.showTemp();
            }
            catch(TempIsZeroException e)
            {
                Console.WriteLine("TempIsZeroException:{0}", e.Message);
            }
            Console.ReadKey();

        }
    }
   //创建自定义异常
    public class TempIsZeroException:ApplicationException
    { 
        public TempIsZeroException(string message):base(message)
        {

        }
    }
    public class Temperture
    {
        int temperature = 0;
        public void showTemp()
        {
            if(temperature==0)
            {
                throw (new TempIsZeroException("Zero Temperature found"));
            }
            else
            {
                Console.WriteLine("Temperature:{0}", temperature);
            }
        }
    }

搜索调用栈的示例

    class Program
    {
        static void Main(string[] args)
        {
            Myclass MCLs = new Myclass();
            try
            {
                MCLs.A();
            }
            catch(DivideByZeroException e)
            {
                Console.WriteLine("catch clause in Main()");
            }
            finally
            {
                Console.WriteLine("finally clause in Main()");
            }
            Console.WriteLine("After try statement in Main");
            Console.WriteLine("----------------------keep runing");
            Console.ReadKey();
        }
    }
    class Myclass
    {
        public void A()
        {
            try
            {
                B();
            }
            catch(System.NullReferenceException)
            {
                Console.WriteLine("catch clause in A()");
            }
            finally
            {
                Console.WriteLine("finally clause in A()");
            }
        }
        void B()
        {
            int x = 10, y = 0;
            try
            {
                x /= y;
            }
            catch(System.IndexOutOfRangeException)
            {
                Console.WriteLine("catch clause in B()");
            }
            finally
            {
                Console.WriteLine("finally clasue in B()");
            }
        }
    }

  • Main调用A,调用B,B遇到一个DivideByZeroExceprion异常。
  • 系统检查B的catch段寻找匹配的catch子句。虽然它有一个Index0ut0fRangeException的子句,但没有DivideByZerException的。
  • 系统然后延着调用栈向下移动并检查A的catch段,在那里它发现A也没有匹配的atch子句
  • 系统继续延调用栈向下,并检查Main的catch子句部分,在那里它发现Main确实有一个DivideByZeroException的catch子句。
  • 尽管匹配的catch子句现在被定位了,但并不执行。相反,系统回到栈的顶端,执行B的finally子句,并把B从调用栈中弹出。
  • 系统移动到A,执行它的fina]1y子句,并把A从调用栈中弹出。
  • 最后,Main的匹配catch子句被执行,接着是它的fina11y子句。然后执行在Main的try语句结尾之后继续。

在这里插入图片描述

异常抛出

可以使用throw语句显式引发一个异常,语法如下:

throw ExceptionObject
    class Program
    {
        static void Main(string[] args)
        {
            //带对象的异常抛出
            string s = null;
            Myclass.PrintArg(s);
            Myclass.PrintArg("hello world");
            Myclass01.PrintArg(s);
            Console.ReadKey();

        }
    }
    class Myclass
    {
        public static void PrintArg(string arg)
        {
            try
            {
                if(arg==null)
                {
                    ArgumentNullException myEx = new ArgumentNullException("arg");
                    throw myEx;
                }
            }
            catch (ArgumentNullException e)
            {
                Console.WriteLine("Message:{0}", e.Message);
            }
        }
    }
    class Myclass01
    {
        public static void PrintArg(string arg)
        {
            try
            {
                try
                {
                    if(arg == null)
                    {
                        ArgumentNullException myEx = new ArgumentNullException("arg");
                        throw myEx;
                    }
                    Console.WriteLine(arg);
                }
                catch(ArgumentNullException e)
                {
                    Console.WriteLine("Inner catch:{0}", e.Message);
                    throw;//重新抛出异常,没有附加参数
                }
            }
            catch
            {
                Console.WriteLine("Outer catch:Handling an Exception.");
            }
        }
    }

本文参考C#图解教程以及博文C#处理Exception的常用方法总结

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C#中,InnerExceptionException类的一个属性,用于获取当前异常对象中包含的内部异常。当一个异常被捕获并包装在另一个异常中时,被捕获的异常就成为内部异常。通过InnerException属性,我们可以访问这个内部异常对象的信息,包括异常类型、错误消息等。 在处理异常时,可以使用try-catch-finally语句来捕获并处理异常。使用不带参数的catch可以捕获所有派生自Exception类的异常,而使用catch(Exception)可以指定捕获特定类型的异常。在catch块中,可以使用InnerException属性来访问内部异常对象。 具体来说,InnerException属性是一个只读属性,它返回一个表示当前异常的内部异常Exception对象。如果当前异常没有内部异常,InnerException属性将返回null。通常,当InnerException属性为空时,意味着当前异常是引起异常状态的根本原因。 总结起来,InnerException属性在C#中用于获取当前异常对象中的内部异常,它能提供有关引起异常的原始异常的信息。通过使用try-catch-finally语句,我们可以处理异常并在需要时访问InnerException属性以获取内部异常的详细信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [c# 中的内部异常(inner Exception)](https://blog.csdn.net/hzh_csdn/article/details/54754940)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [C#异常处理详解](https://download.csdn.net/download/weixin_38735782/14872620)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yue008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值