文档章节

解析Exception和C#处理Exception的常用方法总结

彭泽0902
 彭泽0902
发布于 2016/11/24 18:47
字数 2072
阅读 4
收藏 0
点赞 0
评论 0

    在.NET中,异常是指成员没有完成它的名称宣称可以完成的行动。在异常的机制中,异常和某件事情的发生频率无关。

    异常处理四要素包括:一个表示异常详细信息的类类型;一个向调用者引发异常类实例的成员;调用者的一段调用异常成员的代码块;调用者的一段处理将要发生异常的代码块。异常类类型包括:基类:System.Exception;系统级异常:System.SystemException;应用程序级异常:System.ApplicationException。

   (一).在.NET中有如下的异常类:

     (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 平台不支持某个特定属性时抛出该错误。

(二)..NET的异常处理方式:

      发生异常时,系统将搜索可以处理该异常的最近的 catch 子句(根据该异常的运行时类型来确定)。首先,搜索当前的方法以查找一个词法上包含着它的 try 语句,并按顺序考察与该 try 语句相关联的各个 catch 子句。如果上述操作失败,则在调用了当前方法的方法中,搜索在词法上包含着当前方法调用代码位置的 try 语句。此搜索将一直进行下去,直到找到可以处理当前异常的 catch 子句(该子句指定一个异常类,它与当前引发该异常的运行时类型属于同一个类或是该运行时类型所属类的一个基类)。注意,没有指定异常类的 catch 子句可以处理任何异常。

   找到匹配的 catch 子句后,系统将把控制转移到该 catch 子句的第一条语句。在 catch 子句的执行开始前,系统将首先按顺序执行嵌套在捕捉到该异常的 try 语句里面的所有 try 语句所对应的全部 finally 子句。

      (1).try块:包含的代码通常需要执行一些通用的资源清理操作,或者需要从异常中恢复,或者两者都需要。try块还可以包含也许会抛出异常的代码。

      (2).catch块:包含的是响应一个异常需要执行的代码。如果没有任何捕捉类型与抛出的异常匹配,CLR会去调用栈的更高一层搜索一个与异常匹配的捕捉类型。

      (3).finally块:包含的代码是保证会执行的代码。finally块所有代码执行完毕后,线程退出finally块,执行紧跟在finally块之后的语句。

(三).Exception的常用属性的源码解析:

     (1).Message:包含辅助性文字说明,指出抛出异常的原因。

public virtual String Message {
               get {
                if (_message == null) {
                    if (_className==null) { 
                        _className = GetClassName();
                    } 
                    return Environment.GetRuntimeResourceString("Exception_WasThrown", _className); 

                } else { 
                    return _message;
                }
            }
        } 

    (2).Data:对一个“键/值对”集合的引用。

public virtual IDictionary Data { 
            [System.Security.SecuritySafeCritical]  // auto-generated 
            get {
                if (_data == null) 
                    if (IsImmutableAgileException(this))
                        _data = new EmptyReadOnlyDictionaryInternal();
                    else
                        _data = new ListDictionaryInternal(); 

                return _data; 
            } 
        }

   (3).Source:包含生成异常的程序集名称。

public virtual String Source {
            #if FEATURE_CORECLR 
            [System.Security.SecurityCritical] // auto-generated
            #endif 
            get { 
                if (_source == null)
                { 
                    StackTrace st = new StackTrace(this,true);
                    if (st.FrameCount>0)
                    {
                        StackFrame sf = st.GetFrame(0); 
                        MethodBase method = sf.GetMethod();
 
                        Module module = method.Module; 

                        RuntimeModule rtModule = module as RuntimeModule; 

                        if (rtModule == null)
                        {
                            System.Reflection.Emit.ModuleBuilder moduleBuilder = module as System.Reflection.Emit.ModuleBuilder; 
                            if (moduleBuilder != null)
                                rtModule = moduleBuilder.InternalModule; 
                            else 
                                throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeReflectionObject"));
                        } 

                        _source = rtModule.GetRuntimeAssembly().GetSimpleName();
                    }
                } 

                return _source; 
            } 
            #if FEATURE_CORECLR
            [System.Security.SecurityCritical] // auto-generated 
            #endif
            set { _source = value; }
        }

  (四).异常处理的常用方法:

    (1).提取异常及其内部异常堆栈跟踪

/// <summary>
        /// 提取异常及其内部异常堆栈跟踪
        /// </summary>
        /// <param name="exception">提取的例外</param>
        /// <param name="lastStackTrace">最后提取的堆栈跟踪(对于递归), String.Empty or null</param>
        /// <param name="exCount">提取的堆栈数(对于递归)</param>
        /// <returns>Syste.String</returns>
        public static string ExtractAllStackTrace(this Exception exception, string lastStackTrace = null, int exCount = 1)
        {
            var ex = exception;
            const string entryFormat = "#{0}: {1}\r\n{2}";
            //修复最后一个堆栈跟踪参数
            lastStackTrace = lastStackTrace ?? string.Empty;
            //添加异常的堆栈跟踪
            lastStackTrace += string.Format(entryFormat, exCount, ex.Message, ex.StackTrace);
            if (exception.Data.Count > 0)
            {
                lastStackTrace += "\r\n    Data: ";
                foreach (var item in exception.Data)
                {
                    var entry = (DictionaryEntry)item;
                    lastStackTrace += string.Format("\r\n\t{0}: {1}", entry.Key, exception.Data[entry.Key]);
                }
            }
            //递归添加内部异常
            if ((ex = ex.InnerException) != null)
                return ex.ExtractAllStackTrace(string.Format("{0}\r\n\r\n", lastStackTrace), ++exCount);
            return lastStackTrace;
        }

   (2).检查字符串是空的或空的,并抛出一个异常

/// <summary>
        /// 检查字符串是空的或空的,并抛出一个异常
        /// </summary>
        /// <param name="val">值测试</param>
        /// <param name="paramName">参数检查名称</param>
        public static void CheckNullOrEmpty(string val, string paramName)
        {
            if (string.IsNullOrEmpty(val))
                throw new ArgumentNullException(paramName, "Value can't be null or empty");
        }

  (3).检查参数不是无效,并抛出一个异常

/// <summary>
        /// 检查参数不是无效,并抛出一个异常
        /// </summary>
        /// <param name="param">检查值</param>
        /// <param name="paramName">参数名称</param>
        public static void CheckNullParam(object param, string paramName)
        {
            if (param == null)
                throw new ArgumentNullException(paramName, paramName + " can't be null");
        }

   (4).请检查参数1不同于参数2

/// <summary>
        /// 请检查参数1不同于参数2
        /// </summary>
        /// <param name="param1">值1测试</param>
        /// <param name="param1Name">name of value 1</param>
        /// <param name="param2">value 2 to test</param>
        /// <param name="param2Name">name of vlaue 2</param>
        public static void CheckDifferentsParams(object param1, string param1Name, object param2, string param2Name)
        {
            if (param1 == param2) {
                throw new ArgumentException(param1Name + " can't be the same as " + param2Name,
                    param1Name + " and " + param2Name);
            }
        }

   (5).检查一个整数值是正的(0或更大)

/// <summary>
        /// 检查一个整数值是正的(0或更大)
        /// </summary>
        /// <param name="val">整数测试</param>
        public static void PositiveValue(int val)
        {
            if (val < 0)
                throw new ArgumentException("The value must be greater than or equal to 0.");
        }

    异常处理器(程序):对于程序中出现的异常,在C#中是使用一种被称为“异常处理器(程序)”的错误捕获机制来进行处理的, 你可以认为异常处理器(程序)就是发生错误时,能够接受并处理错误的接受者和处理。

© 著作权归作者所有

共有 人打赏支持
彭泽0902
粉丝 0
博文 44
码字总数 57771
作品 0
武汉
高级程序员
Java常用异常整理

填坑,整理下Java的常用异常。正确使用异常在实际编码中非常重要,但面试中的意义相对较小,因为对异常的理解和应用很难通过几句话或几行代码考查出来,不过我们至少应答出三点:异常类的继承...

monkeysayhi ⋅ 2017/11/14 ⋅ 0

C#异常处理及心得

C sharp中的异常用于处理系统级和应用程序级的错误状态,它是一种结构化、统一的类型安全的处理机制。c#的异常 机制非常类似于c++的异常处理机制,但是还是有一些重要的区别: 1,在 C# 中,...

C2056LOVE ⋅ 2013/10/17 ⋅ 0

Android中XML解析模块的使用方法

在音乐跟电视的项目中,很多都是使用了典型的按照接口规范的流程处理方式。 例如上图,客户端发送一个request请求,服务端就会以xml的数据格式返回一个response响应。但是在客户端界面展示x...

晨曦之光 ⋅ 2012/03/05 ⋅ 2

springmvc方法参数处理

基础 类名称 HandlerMethodArgumentResolver 解决方法参数到指定信息参数集合的策略接口。 方法名称 supportsParameter检查指定参数是否被该接口支持参数MethodParameter parameter要被检查的...

hyssop ⋅ 2016/07/21 ⋅ 0

为何XML解析器传入参数是InputStream或InputSource时提示找不到XSD?

常用的XML解析器DocumentBuilder的parse方法不同参数,却有区别: 当parse方法的参数是File或URI时,正常,可以通过XSD验证XML文档,并读取文档内容。 当parse方法的参数是InputStream或Inp...

bear13 ⋅ 2017/08/11 ⋅ 0

C#调用控制面板选项

因为C#是由Microsoft公司推出的,所以它对Microsoft的所有产品的兼容性与相互操作性是其它公司开发出的编程语言所不及的。Microsoft开发的Windows操作系统与C#之间的关系也非常紧密。从而实现...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

JDBC和异常总结及常见使用

JDBC -一、JDBC连接过程 01.注册驱动 Class.forName("oracle.jdbc.driver.OracleDriver"); 02.获取连接 Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@10.0.19.252:152......

花开半夏qb ⋅ 2017/09/15 ⋅ 0

PHP中的依赖注入(DI)容器

介绍 我们已经介绍过了PHP 反射API,阐明了什么是反射API,以及它的不同用途,其中一种 - 最常见的是将其与 一起使用,以下是本文的主要内容: 什么是依赖注入 注入对象的不同方式(以及为什...

如来神掌 ⋅ 06/03 ⋅ 0

JEE开发异常处理

在Java开发中,到处可见Exception或者它的子类。如何在一个已有的框架中或者自己的项目中利用好异常,而不让异常漫天飞,需要开发的积累和总结,这篇日志就为这个目的总结几年来的开发对异常...

xdev ⋅ 2013/03/17 ⋅ 0

[每日一题]说说异常处理机制和最佳实践

这个问题仁者见仁智者见智,每个人心中的最佳实践不见得一致,但是你要有想法,这个很关键,如果连思考都没有思考过,那就不太好了。 很多高级语言都提供了异常处理,比如Java、Python、Rub...

UlricQin ⋅ 2014/09/27 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

解决CentOS6、7,/etc/sysconfig/下没有iptables的问题

一、Centos 6版本解决办法: 1.任意运行一条iptables防火墙规则配置命令: iptables -P OUTPUT ACCEPT 2.对iptables服务进行保存: service iptables save 3.重启iptables服务: service ...

寰宇01 ⋅ 10分钟前 ⋅ 1

数据库备份和恢复

备份:mysqldump -u root -p 数据库>磁盘路径 恢复:mysql -u root -p 数据库<sql脚本的磁盘路径

anlve ⋅ 55分钟前 ⋅ 0

发生了什么?Linus 又发怒了?

在一个 Linux 内核 4.18-rc1 的 Pull Request 中,开发者 Andy Shevchenko 表示其在对设备属性框架进行更新时,移除了 union 别名,这引发了 Linus 的暴怒。 这一次 Linus Torvalds 发怒的原...

问题终结者 ⋅ 今天 ⋅ 0

在树莓派上搭建一个maven仓库

在树莓派上搭建一个maven仓库 20180618 lambo init 项目说明 家里有台树莓派性能太慢。想搭建一个maven私服, 使用nexus或者 jfrog-artifactory 运行的够呛。怎么办呢,手写一个吧.所在这个...

林小宝 ⋅ 今天 ⋅ 0

Spring发展历程总结

转自与 https://www.cnblogs.com/RunForLove/p/4641672.html 目前很多公司的架构,从Struts2迁移到了SpringMVC。你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢?...

onedotdot ⋅ 今天 ⋅ 0

Python模块/包/库安装(6种方法)

Python模块/包/库安装(6种方法) 冰颖机器人 2016-11-29 21:33:26 一、方法1: 单文件模块 直接把文件拷贝到 $python_dir/Lib 二、方法2: 多文件模块,带setup.py 下载模块包(压缩文件zip...

cswangyx ⋅ 今天 ⋅ 0

零基础学习大数据人工智能,学习路线篇!系统规划大数据之路?

大数据处理技术怎么学习呢?首先我们要学习Python语言和Linux操作系统,这两个是学习大数据的基础,学习的顺序不分前后。 Python:Python 的排名从去年开始就借助人工智能持续上升,现在它已经...

董黎明 ⋅ 今天 ⋅ 0

openJdk和sun jdk的区别

使用过LINUX的人都应该知道,在大多数LINUX发行版本里,内置或者通过软件源安装JDK的话,都是安装的OpenJDK, 那么到底什么是OpenJDK,它与SUN JDK有什么关系和区别呢? 历史上的原因是,Ope...

jason_kiss ⋅ 今天 ⋅ 0

梳理

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。 它是JS的状态容器,是一种解决问题的方式,所以即可以用于 react 也可以用于 vue。 需要理解其思想及实现方式。 应用中所有的 stat...

分秒 ⋅ 今天 ⋅ 0

Java 后台判断是否为ajax请求

/** * 是否是Ajax请求 * @param request * @return */public static boolean isAjax(ServletRequest request){return "XMLHttpRequest".equalsIgnoreCase(((HttpServletReques......

JavaSon712 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部