• 异常处理 Exception


    一、异常类

    1、在C#中所有的异常都是使用一个异常类型的示例对象表示的,这些异常类型都是继承自System.Exception类型,或者直接使用System.Exception类型的实例对象;

    2、在C#中,位于finally块中的代码可以保证不管代码是正常结束,还是进入异常处理代码块,其中的语句均会被执行。

    System.Exception类有一些属性值得注意,这些属性被所有从此类派生的异常类共享,这些属性是:

      Message:一个只读字符串,此属性为当前的异常提供了描述性信息;

      InnerException:一个Exception类型的只读属性,如果它的值不为null,则可以通过它的值获取导致当前异常的异常实例;反之,如果其值为null,则表示当前异常不是由其他异常引发的。

      StackTrace:一个只读字符串,此属性描述了异常发生时调用堆栈的内容,其中首先显示最近的方法调用。

    二、抛出异常

      当程序有错误的时候可以创建一个描述该错误的异常对象,然后用throw关键字抛出异常对象,抛出的异常对象将被当前代码的更上层代码所捕获,或者不处理直接抛出,或者干脆不予捕获。那么该异常将一直向上传递,直到有人捕获并处理它。

    复制代码
        class Program
        {
            static void Main(string[] args)
            {
                DoSomething(null);
    
                Console.ReadKey();
            }
    
            public static void DoSomething(string name)
            {
                if (name == null)
                {
                    throw new ArgumentException("参数不能为空!");
                }
            }
        }
    复制代码

    三、捕获异常

      可以使用try/catch来捕获并选择是否处理异常,捕获了异常并非一定要处理异常,还可以将异常转换为另一个异常后再抛出,或者仅仅是记录异常的信息。

      要记住,始终必须按照从最特定到最不特定(从具体到一般)的顺序对catch块中处理的异常进行排序,这个原则可以保证在将某个特定异常传递给更一般的异常的catch块之前处理该异常。

      try/catch块有三种形式:try-catch、try-finally、try-catch-finally,不带有catch或finally块的try语句将导致编译器错误。

      try语句中的代码是可能抛出异常的代码,catch块捕捉某种特定的异常并加以处理。这些catch块可以有多个,并且catch块可以串联在一起,如果存在多个catch块,那么计算顺序是从顶部到底部。但是对于所引发的每个异常,都只执行一个catch块。

      1、好的编程的做法是捕获特定类型的异常,而不是捕获更常规的异常。

      2、如果捕获特定类型的catch块捕获异常的基类型catch块同时存在,则前者要位于后者之前,否则将无法通过编译。

    复制代码
        class Program
        {
            static void Main(string[] args)
            {
                DoSomething(null);
    
                Console.ReadKey();
            }
    
            public static void DoSomething(string name)
            {
    
                try
                {
                    Console.WriteLine(name);
                    if (name == null)
                    {
                        throw new ArgumentException("参数不能为空!");
                    }
                }
                catch (ArgumentException ex)
                {
                    name = "你好";
                    DoSomething(name);
                    Console.WriteLine(ex.Message);
    
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
    
                }
            }
        }
    复制代码

    四、自定义的异常类

      要创建用户自定义异常类,需要遵循以下几点

      1、从System.ApplicationException或者System.Exception类派生。

      2、使用"Exception"这个词作为自定义的异常名称的后缀。

      3、至少提供三个公共函数。

      4、一个不包含参数的默认构造函数。

      5、一个可以包含异常消息的构造函数,只有一个参数:message。

      6、一个可以包含异常消息,以及引发该异常的异常引用的构造函数,这两个参数分别是message和innerException。

    复制代码
        public class OneException : System.ApplicationException
        {
            public OneException() { }
            public OneException(string message) : base(message){}
            public OneException(string message,System.Exception innerException) : base(message,innerException){}
        }
    复制代码

    五、异常处理原则

      1、尽量由程序自动处理异常。当异常发生时,程序在捕获后应该先尝试处理异常,如果错误得以排序,那么程序可以恢复正常,而不是每次捕获异常就立刻通知用户来处理,或者仅仅把异常信息记录下来。例如网络传送发生连接错误,应该先重连几次,然后再通知用户处理。

      2、限制异常范围,应该尽量地减少缩小异常处理的范围,如果只需要检测某一行代码可能发生异常,就不要把整段的代码都放进try语句块中。

      3、应该捕获更具体的异常。尽量避免直接捕获Exception异常。

      4、尽可能在上层捕获并处理异常。

      5、应该将异常信息保存在日志中。

     突然回忆起上次面试的一段代码:

    复制代码
        class Program
        {
            static void Main(string[] args)
            {
                string name = GetName();
                Console.WriteLine(name);  //输出 就算return了这行也会执行哦!
                           //输出 你好
                Console.ReadKey();
            }
    
            public static string GetName()
            {
                try
                {
                    return "你好";
                }
                catch (Exception ex)
                {
                    return "捕捉到异常!";
                }
                finally
                {
                    Console.WriteLine("就算return了这行也会执行哦!");
                }
            }
        }
    复制代码

      留意到,几时是没抛出异常同时return了也执行了finally里面的代码。

  • 相关阅读:
    SpringMvc上手学习
    UITapGestureRecognizer 和 UICollectionView、UITableView的点击事件冲突问题
    Omnigraffle 许可证
    REACT-NATIVE
    iOS @property、@synthesize和@dynamic
    WWDC2018 之 优化 App Assets Optimizing App Assets
    WWDC2018 之 高性能 Auto Layout
    链表
    Your development team, "", does not support the Push Notifications capability.
    xcode无线调试
  • 原文地址:https://www.cnblogs.com/lyl6796910/p/4513992.html
Copyright © 2020-2023  润新知