在.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#中是使用一种被称为“异常处理器(程序)”的错误捕获机制来进行处理的, 你可以认为异常处理器(程序)就是发生错误时,能够接受并处理错误的接受者和处理。

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

C#处理Exception的常用方法总结的更多相关文章

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

    在.NET中,异常是指成员没有完成它的名称宣称可以完成的行动.在异常的机制中,异常和某件事情的发生频率无关. 异常处理四要素包括:一个表示异常详细信息的类类型:一个向调用者引发异常类实例的成员:调用者 ...

  2. Java编程思想学习(九) 异常处理

    java的异常处理机制可以使程序有极好的容错性,让程序更加的健壮.所谓的异常,就是指的阻止当前方法或作用域继续执行的问题,,当程序运行时出现异常时,系统就会自动生成一个Exception对象来通知程序 ...

  3. JavaEE系列之(一)JSP基础知识详解

    一.JSP基础语法     1.JSP简介        JSP(Java Server Pages),其根本是一个简化的Servlet设计,它实现了在Java中使用HTML标签.JSP是一种动态网页 ...

  4. JSP九大内置对象与Servlet学习笔记[转]

    我们常说的JSP有九大内置对象分别为:request.response.session.out.pagecontext.page.exception.application.config. 我们知道, ...

  5. 面试题:jsp九大内置对象

    我们常说的JSP有九大内置对象分别为:request.response.session.out.pagecontext.page.exception.application.config. 我们知道, ...

  6. exception对象的使用及常用方法

    exception对象的使用及常用方法 制作人:全心全意 exception对象用来处理JSP文件执行时发生的所有错误和异常,只有在page指令中设置为isErrorPage属性值为true的页面中才 ...

  7. Date和Calendar时间操作常用方法及示例

    package test; import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date; /** ...

  8. Java中从控制台输入数据的几种常用方法

    Java中从控制台输入数据的几种常用方法 一.使用标准输入串System.in //System.in.read()一次只读入一个字节数据,而我们通常要取得一个字符串或一组数字 //System.in ...

  9. 基础学习day12--多线程一线程之间的通信和常用方法

    一.线程之间的通信 1.1.线程之间的通信方法 多个线程在处理统一资源,但是任务却不同,这时候就需要线程间通信.    等待/唤醒机制涉及的方法:    1. wait():让线程处于冻结状态,被wa ...

随机推荐

  1. Golang中defer、return、返回值之间执行顺序的坑

    原文链接:https://studygolang.com/articles/4809 Go语言中延迟函数defer充当着 cry...catch 的重任,使用起来也非常简便,然而在实际应用中,很多go ...

  2. STL_string

    将string对象利用c风格的形式输出函数:  c_str() 栗子:      string s;      printf("%s\n",s.c_str());

  3. 关于初级dp的一些记忆

    01背包和数塔都是寒假看的,数塔还算明白,但01背包虽然会做其实也是背下来的,一直不是很清楚它的可行性,昨天老师讲了以后恍然大悟,和数塔类似生成了一颗二叉树: 利用数组/dfs  自下而上/自上而下 ...

  4. 原生JS和jQuery版实现文件上传功能

    <!doctype html> <html lang="zh"> <head> <meta charset="utf-8&quo ...

  5. OC Foundation框架—字符串操作方法及习题

    #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { ...

  6. js数组的方法小结

    js中数组是一种非常常用数据结构,而且很容易模拟其他的一些数据结构,比如栈和队列.数组的原型Array.prototype内置了很多方法,下面就来小小总结一下这些方法. 检测数组就不用多说了,使用EC ...

  7. 封装一个简单的原生js焦点轮播图插件

    轮播图实现的效果为,鼠标移入左右箭头会出现,可以点击切换图片,下面的小圆点会跟随,可以循环播放(为了方便理解,没有补2张图做无缝轮播).本篇文章的主要目的是分享封装插件的思路. 轮播图我一开始是写成非 ...

  8. jquery条形码生成器

    <!DOCTYPE html><html> <head>        <meta charset="UTF-8">         ...

  9. PHP excel reader , excel时间转成php时间格式

    最近,在做一个导入功能,在系统中使用PHPExcel类库,读取上传的Excel文件,然后进行字段映射,最后将Excel内的数据导入到系统中.其中,关于日期格式的导入,使我犯了难. 首先,如何导入日期, ...

  10. L1-031 到底是不是太胖了

    据说一个人的标准体重应该是其身高(单位:厘米)减去100.再乘以0.9所得到的公斤数.真实体重与标准体重误差在10%以内都是完美身材(即 | 真实体重 − 标准体重 | < 标准体重×10%). ...