年关拿到,对于大多数程序员来说,马上就是可闲下来一段时间了,然而当这个闲暇的日里,唯有争论哪门语言更好可以消磨时光,估计最近会产生许多有关java与.net的博文出现,我表示如作一个凭着瓜群众,静静的羁押正在大佬们上心情。

   

    以上的废话说的足够多了,这里就不再赘述了,还是切入主题吧。

   
年关拿到,对于大多数程序员来说,马上就可以闲下来一段时间了,然而以这闲暇的日里,唯有争论哪门语言更好可以消磨时光,估计最近会晤有广大有关java与.net的博文出现,我表示如果作为一个凭着瓜群众,静静的禁闭正在大佬们上心情。

   
在列开中,对于网和代码的安宁与容错性都是有对应之求。实际付出项目受到的代码和样例代码的区别,更多的凡当代码的周转的稳定性、容错性、扩展性的比较。因为对于贯彻一个成效来说,实现效益的主干代码是平等的,可能只是当写法上优化而已,但是以促成有一个操作上以的类似来说,这或多或少凡是大部分时是如出一辙的。这样看来,我们以事实上开发之历程遭到,需要考虑的题材比多,已经不仅仅局限为某平等切实的职能实现,更多之是代码的安宁与扩展性考虑。

    以上的废话说的足够多了,这里就不再赘述了,还是切入主题吧。

   
以上是当实际上开发中待直面的题材,笔者在近来之博文被,也于考虑是可怜到底得怎么去描绘,以及非常到底要怎么去领悟,在博文中,也来那么些底园友对那个的写法与处理提出了祥和的理念,在此处我哪怕形容一下协调之部分解,可能勾的于浅显和精炼,但是一味当是一个引子,可以引出大佬们来谈谈自己之实际上项目更。希望对大家来一个救助,也接大家提出好的想法跟观,分享温馨之知识以及见解。

   
在品种开支中,对于网及代码的风平浪静与容错性都是有对应之求。实际支出项目受到之代码和样例代码的分别,更多的是于代码的运行的安定团结、容错性、扩展性的比较。因为对此落实一个作用来说,实现效益的中坚代码是平等的,可能只是当写法上优化而已,但是在实现有一个操作及行使的好像来说,这一点凡是大多数上是均等的。这样看来,我们在实际上支付的过程遭到,需要考虑的题材比多,已经不仅仅局限为某某平等切实可行的效果实现,更多之凡代码的祥和和扩展性考虑。

一.DotNET好的概述:

   
谈到大,我们尽管需理解呀叫做异常,万事万物如果我们纪念去学,就相应明了我们而学习的物是呀,这样以心尖可有一个大概的体味。异常是因成员没有完其的名号宣称可得的行路。在.NET中,构造器、获取与安装属性、添加和去事件、调用操作符重载和调用转换操作符等等都没有办法回去错误代码,但是以这些组织中还要要报错误,那便必提供十分处理机制。

   
在特别的处理着,我们常利用及之老三个片分别是:try块;catch块;finally块。这三只片好合使用,也得以无写catch块使用,异常处理块好嵌套使用,具体的措施以下面会介绍到。

   
在雅的处理机制中,一般有三栽选择:重新抛来同之那个,向调用栈高一交汇的代码通知该老的发出;抛出一个不一的可怜,想调用栈高一叠代码提供更丰富的很信息;让线程从catch块的根退出。 
 

   有关好的处理方式,有一对指导性的提议。

   
以上是于事实上付出被得面对的题材,笔者于近期之博文中,也在设想是可怜到底需要怎么去描绘,以及老到底要怎么去领略,在博文中,也来成千上万的园友对那个的写法与处理提出了祥和之见地,在此地自己不怕形容一下温馨之部分知情,可能勾的于浅显和精炼,但是一味当是一个引子,可以引出大佬们来讨论自己之实在项目阅。希望对大家有一个助,也接大家提出自己之想法跟看法,分享自己的知识以及意见。

       1.相宜的行使finally块:

         
 finally块可以管不管线程抛来什么种的挺都好为实施,finall块一般用来做清理那些已经成功启动的操作,然后又回来调用者或者finally块之后的代码。

一.DotNET老大的概述:

   
谈到那个,我们就是需要懂得呀叫做异常,万事万物如果我们想去念,就当明白我们而上学之东西是呀,这样在心底同意有一个盖的体会。异常是依赖成员没有水到渠成其的号宣称可做到的行进。在.NET中,构造器、获取和安属性、添加和去事件、调用操作符重载和调用转换操作符等等都无主意回到错误代码,但是于这些组织中以欲报错误,那就不能不提供好处理体制。

   
在生的处理着,我们常常利用到的老三单片分别是:try块;catch块;finally块。这三只片好共同以,也可免写catch块使用,异常处理块好嵌套使用,具体的艺术以底下会介绍至。

   
在充分的处理机制面临,一般发生三种植选择:重新抛来同样之酷,向调用栈高一重叠的代码通知该特别的来;抛出一个差之死,想调用栈高一层代码提供更丰富的慌信息;让线程从catch块的底层退出。 
 

   有关好的处理方式,有局部指导性的提议。

       2.雅捕捉消方便:

         
 为什么而得体的捕捉异常与否?如下代码,因为咱们无能够呀大且失去捕捉,在破获异常后,我们得去处理这些特别,如果我们以有的那个且捕捉后,但是从未预见会起的不行,我们就是无章程去处理这些大。

       
 如果应用程序代码抛来一个那个,应用程序的别一样端则可能预期而捕捉这个非常,因此无能够写成一个”大小通吃“的深块,应该允许该大在调用栈中向上走,让应用程序代码针对性地拍卖是很。

       
 在catch块中,可以采用System.Exception捕捉异常,但是太好当catch块末尾重新抛来特别。至于因在末端会教到。

          try
            {
                var hkml = GetRegistryKey(rootKey);
                var subkey = hkml.CreateSubKey(subKey);
                if (subkey != null && keyName != string.Empty)
                    subkey.SetValue(keyName, keyValue, RegistryValueKind.String);
            }
            catch (Exception ex)
            {
                Log4Helper.Error("创建注册表错误" + ex);
                throw new Exception(ex.Message,ex);
            }

       1.正好的应用finally块:

         
 finally块可以包不管线程抛来什么品种的异常且可于实践,finall块一般用来举行清理那些已经打响启动之操作,然后又回去调用者或者finally块之后的代码。

       3.打生中恢复:

         
 我们在抓获异常后,可以针对的状一些百般恢复的代码,可以让程序继续运行。在抓获异常时,需要捕获具体的很,充分的左右在啊状态下会丢掉来很,并懂得打捕获的老类型派生出了那些类型。除非在catch块的末梢重新抛来大,否则不要处理要捕获System.Exception异常。

       2.老捕捉消适度:

         
 为什么要适宜的捕捉异常与否?如下代码,因为咱们无克啊特别都失去捕捉,在抓获异常后,我们得去处理这些异常,如果我们以享有的非常且捕捉后,但是没预见会发出的特别,我们虽从来不主意去处理这些老。

       
 如果应用程序代码抛来一个万分,应用程序的外一样端则恐预期使捕捉这个大,因此不可知写成一个”大小通吃“的要命块,应该允许该特别在调用栈中向上走,让应用程序代码针对性地处理此那个。

       
 在catch块中,可以以System.Exception捕捉异常,但是最好于catch块末尾重新抛来老。至于原因在背后会教到。

图片 1

          try
            {
                var hkml = GetRegistryKey(rootKey);
                var subkey = hkml.CreateSubKey(subKey);
                if (subkey != null && keyName != string.Empty)
                    subkey.SetValue(keyName, keyValue, RegistryValueKind.String);
            }
            catch (Exception ex)
            {
                Log4Helper.Error("创建注册表错误" + ex);
                throw new Exception(ex.Message,ex);
            }

图片 2

      4.保持状态:

         
一般情形下,我们做到一个操作还是一个智时,需要调用几个章程结合形成,在实行的进程遭到见面现出前几只艺术就,后面的不二法门有大。发生不可恢复的死去活来时回滚部分成功的操作,因为咱们要还原信息,所有我们当抓获异常时,需要捕获所有的十分信息。

       3.于那个中还原:

         
 我们以抓获异常后,可以针对的描绘一些可怜恢复的代码,可以为程序继续运行。在捕获异常时,需要捕获具体的好,充分的掌握在啊状况下会丢来大,并了解打捕获的深类型派生出了那些类型。除非在catch块的末梢重新抛来特别,否则不要处理要捕获System.Exception异常。

      5.伏实现细节来维持契约:

         
有时可能需要捕捉一个异常并再次抛来一个不同的死去活来,这样好保障方法的契约,抛来底心里大类型地应当是一个有血有肉的万分。看如下代码:

FileStream fs = null;
            try
            {
                fs = FileStream();

            }
            catch (FileNotFoundException e)
            {
          //抛出一个不同的异常,将异常信息包含在其中,并将原来的异常设置为内部异常
                throw new NameNotFoundException();
            }
            catch (IOException e)
            {

               //抛出一个不同的异常,将异常信息包含在其中,并将原来的异常设置为内部异常

             throw new NameNotFoundException(); 
            } 
            finally 
            {
               if (fs != null) 
                { 
               fs.close(); 
            } 
            }

   
 以上的代码只是在证实一栽处理方式。应该于丢来的有所特别都挨方法的调用栈向上传递,而未是把他们”吞噬“了后来丢弃来一个初的很。如果一个类别构造器抛来一个好,而且该大未以档次构造器方法吃捕获,CLR就见面于中间捕获该老,并转移吧抛弃来一个新的TypeInitialztionException。

      4.保障状态:

         
一般景象下,我们好一个操作还是一个措施时,需要调用几个方式结合形成,在实行的过程被会现出前几独办法好,后面的点子发生甚。发生不可恢复的特别时回滚部分就的操作,因为我们用恢复信息,所有我们以破获异常时,需要捕获所有的百般信息。

二.DotNET异常的常用处理体制:

     
在代码有特别后,我们需要去处理此坏,如果一个生没有到手及时的拍卖,CLR会终止进程。在非常的处理着,我们可以在一个线程捕获异常,在另一个线程中重新抛来特别。异常抛来时,CLR会在调用栈中向上查找和抛来的雅类型匹配的catch块。如果没有其它catch块匹配抛来底怪类型,就发出一个无处理好。CLR检测及过程遭到的旁线程有一个各处理好,都见面告一段落进程。

      5.躲藏实现细节来保障契约:

         
有时可能用捕捉一个百般并重复抛来一个不一之特别,这样可保持方法的契约,抛来之心底殊类型地应是一个切实的不胜。看如下代码:

图片 3

FileStream fs = null;
            try
            {
                fs = FileStream();

            }
            catch (FileNotFoundException e)
            {
          //抛出一个不同的异常,将异常信息包含在其中,并将原来的异常设置为内部异常
                throw new NameNotFoundException();
            }
            catch (IOException e)
            {

               //抛出一个不同的异常,将异常信息包含在其中,并将原来的异常设置为内部异常

             throw new NameNotFoundException(); 
            } 
            finally 
            {
               if (fs != null) 
                { 
               fs.close(); 
            } 
            }

图片 4

   
 以上的代码只是以证实一种处理方式。应该吃弃来底保有特别且挨方法的调用栈向上传递,而非是管他们”吞噬“了后来丢弃来一个初的很。如果一个类型构造器抛来一个大,而且该老未当品种构造器方法中捕获,CLR就见面以其中捕获该大,并改变吗抛弃来一个新的TypeInitialztionException。

     1.死处理块:

     
 (1).try块:包含代码通常需执行有通用的资源清理操作,或者需要由老中平复,或者两者都需要。try块还可以蕴涵也许会废弃来异常的代码。一个try块至少发生一个关系的catch块或finall块。 
     

     
 (2).catch块:包含的是响应一个不行需要实施的代码。catch关键字后的圆括号被之表达式是捕获类型。捕获类型从System.Exception或者其派生类指定。CLR自上而下搜素一个相当的catch块,所以应该使具体的那个放在顶部。一旦CLR找到一个有所相当捕获类型的catch块,就见面实施内层所有finally块中之代码,”内层finally“是指抛来老的tey块开始,到相当异常的catch块之间的备finally块。

     
 使用System.Exception捕捉异常后,可以采取以catch块的尾声重新抛来很,因为如果我们在捕获Exception异常后,没有就的处理还是已程序,这同一特别或者对先后造成大充分之安全隐患,Exception类是独具特别的基类,可以捕获程序中兼有的杀,如果出现比较充分的死,我们从未当即的处理,造成的问题是了不起的。

     
 (3).finally块:包含的代码是保证会执行的代码。finally块的装有代码执行完毕后,线程退出finally块,执行紧跟在finally块之后的言辞。如果无设有finally块,线程将起最终一个catch块之后的讲话开始履行。

     
备注:异常块好组合及嵌套,对于三单深块的样例,在此间就是非举行牵线,异常的嵌套可以预防在拍卖非常的上再次出现未处理的可怜,以上这些就是不再赘言。

二.DotNET异常的常用处理机制:

     
在代码有大后,我们得去处理这个坏,如果一个格外没有得到这的处理,CLR会终止进程。在雅的拍卖着,我们可以一个线程捕获异常,在任何一个线程中重新抛来非常。异常抛来时,CLR会在调用栈中向上查找和抛来底慌类型匹配的catch块。如果没另外catch块匹配抛来之不可开交类型,就起一个休处理好。CLR检测到过程面临的外线程有一个个处理好,都见面停进程。

    2.很处理实例:

     1.颇处理块:

     
 (1).try块:包含代码通常需实施有通用的资源清理操作,或者需要从杀中平复,或者两者都得。try块还足以分包也许会丢来深的代码。一个try块至少发生一个涉嫌的catch块或finall块。 
     

     
 (2).catch块:包含的是响应一个特别需要实践的代码。catch关键字后的圆括号被的表达式是捕获类型。捕获类型从System.Exception或者其派生类指定。CLR自上而下搜素一个匹的catch块,所以应让具体的酷放在顶部。一旦CLR找到一个备相当捕获类型的catch块,就会见履行内层所有finally块中之代码,”内层finally“是借助抛来特别的tey块开始,到相当异常的catch块之间的有finally块。

     
 使用System.Exception捕捉异常后,可以采用以catch块的末段重新抛来非常,因为一旦我们在捕获Exception异常后,没有马上的处理还是停止程序,这同生或者对先后造成大十分之安全隐患,Exception类是有着特别的基类,可以捕获程序中有的老大,如果出现较充分的那个,我们从没这的处理,造成的题材是英雄的。

     
 (3).finally块:包含的代码是保证会执行的代码。finally块的具有代码执行完毕后,线程退出finally块,执行紧跟以finally块之后的语句。如果无设有finally块,线程将自最终一个catch块之后的语开始推行。

     
备注:异常块好整合以及嵌套,对于三单非常块的样例,在这边就非开牵线,异常的嵌套可以预防在拍卖非常的早晚再次出现未处理的死,以上这些就不再赘言。

       (1).异常处理扩展方法:
        /// <summary>
        ///  格式化异常消息
        /// </summary>
        /// <param name="e">异常对象</param>
        /// <param name="isHideStackTrace">是否隐藏异常规模信息</param>
        /// <returns>格式化后的异常信息字符串</returns>
        public static string FormatMessage(this Exception e, bool isHideStackTrace = false)
        {
            var sb = new StringBuilder();
            var count = 0;
            var appString = string.Empty;
            while (e != null)
            {
                if (count > 0)
                {
                    appString += "  ";
                }
                sb.AppendLine(string.Format("{0}异常消息:{1}", appString, e.Message));
                sb.AppendLine(string.Format("{0}异常类型:{1}", appString, e.GetType().FullName));
                sb.AppendLine(string.Format("{0}异常方法:{1}", appString, (e.TargetSite == null ? null : e.TargetSite.Name)));
                sb.AppendLine(string.Format("{0}异常源:{1}", appString, e.Source));
                if (!isHideStackTrace && e.StackTrace != null)
                {
                    sb.AppendLine(string.Format("{0}异常堆栈:{1}", appString, e.StackTrace));
                }
                if (e.InnerException != null)
                {
                    sb.AppendLine(string.Format("{0}内部异常:", appString));
                    count++;
                }
                e = e.InnerException;
            }
            return sb.ToString();
        }

    2.很处理实例:

     (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");
        }

        /// <summary>
        /// 请检查参数不是空的或空的,并抛出异常
        /// </summary>
        /// <param name="param">检查值</param>
        /// <param name="paramName">参数名称</param>
        public static void CheckNullParam(string param, string paramName)
        {
            if (string.IsNullOrEmpty(param))
                throw new ArgumentNullException(paramName, paramName + " can't be neither null nor empty");
        }

        /// <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");
        }

        /// <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);
            }
        }

        /// <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.");
        }
       (1).异常处理扩展方法:

图片 5

        /// <summary>
        ///  格式化异常消息
        /// </summary>
        /// <param name="e">异常对象</param>
        /// <param name="isHideStackTrace">是否隐藏异常规模信息</param>
        /// <returns>格式化后的异常信息字符串</returns>
        public static string FormatMessage(this Exception e, bool isHideStackTrace = false)
        {
            var sb = new StringBuilder();
            var count = 0;
            var appString = string.Empty;
            while (e != null)
            {
                if (count > 0)
                {
                    appString += "  ";
                }
                sb.AppendLine(string.Format("{0}异常消息:{1}", appString, e.Message));
                sb.AppendLine(string.Format("{0}异常类型:{1}", appString, e.GetType().FullName));
                sb.AppendLine(string.Format("{0}异常方法:{1}", appString, (e.TargetSite == null ? null : e.TargetSite.Name)));
                sb.AppendLine(string.Format("{0}异常源:{1}", appString, e.Source));
                if (!isHideStackTrace && e.StackTrace != null)
                {
                    sb.AppendLine(string.Format("{0}异常堆栈:{1}", appString, e.StackTrace));
                }
                if (e.InnerException != null)
                {
                    sb.AppendLine(string.Format("{0}内部异常:", appString));
                    count++;
                }
                e = e.InnerException;
            }
            return sb.ToString();
        }

图片 6

     (3).Try-Catch扩展操作:
        /// <summary>
        ///     对某对象执行指定功能与后续功能,并处理异常情况
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="source">值</param>
        /// <param name="action">要对值执行的主功能代码</param>
        /// <param name="failureAction">catch中的功能代码</param>
        /// <param name="successAction">主功能代码成功后执行的功能代码</param>
        /// <returns>主功能代码是否顺利执行</returns>
        public static bool TryCatch<T>(this T source, Action<T> action, Action<Exception> failureAction,
            Action<T> successAction) where T : class
        {
            bool result;
            try
            {
                action(source);
                successAction(source);
                result = true;
            }
            catch (Exception obj)
            {
                failureAction(obj);
                result = false;
            }
            return result;
        }

        /// <summary>
        ///     对某对象执行指定功能,并处理异常情况
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="source">值</param>
        /// <param name="action">要对值执行的主功能代码</param>
        /// <param name="failureAction">catch中的功能代码</param>
        /// <returns>主功能代码是否顺利执行</returns>
        public static bool TryCatch<T>(this T source, Action<T> action, Action<Exception> failureAction) where T : class
        {
            return source.TryCatch(action,
                failureAction,
                obj => { });
        }

        /// <summary>
        ///     对某对象执行指定功能,并处理异常情况与返回值
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <typeparam name="TResult">返回值类型</typeparam>
        /// <param name="source">值</param>
        /// <param name="func">要对值执行的主功能代码</param>
        /// <param name="failureAction">catch中的功能代码</param>
        /// <param name="successAction">主功能代码成功后执行的功能代码</param>
        /// <returns>功能代码的返回值,如果出现异常,则返回对象类型的默认值</returns>
        public static TResult TryCatch<T, TResult>(this T source, Func<T, TResult> func, Action<Exception> failureAction,
            Action<T> successAction)
            where T : class
        {
            TResult result;
            try
            {
                var u = func(source);
                successAction(source);
                result = u;
            }
            catch (Exception obj)
            {
                failureAction(obj);
                result = default(TResult);
            }
            return result;
        }

        /// <summary>
        ///     对某对象执行指定功能,并处理异常情况与返回值
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <typeparam name="TResult">返回值类型</typeparam>
        /// <param name="source">值</param>
        /// <param name="func">要对值执行的主功能代码</param>
        /// <param name="failureAction">catch中的功能代码</param>
        /// <returns>功能代码的返回值,如果出现异常,则返回对象类型的默认值</returns>
        public static TResult TryCatch<T, TResult>(this T source, Func<T, TResult> func, Action<Exception> failureAction)
            where T : class
        {
            return source.TryCatch(func,
                failureAction,
                obj => { });
        }

   
 本文没有现实介绍try,catch,finally的下,而是让起片于通用的方法,主要是形似的开发者对于三只片的应用都发出一个认识,就不再做更的牵线。

     (2).验证异常:

图片 7

       /// <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");
        }

        /// <summary>
        /// 请检查参数不是空的或空的,并抛出异常
        /// </summary>
        /// <param name="param">检查值</param>
        /// <param name="paramName">参数名称</param>
        public static void CheckNullParam(string param, string paramName)
        {
            if (string.IsNullOrEmpty(param))
                throw new ArgumentNullException(paramName, paramName + " can't be neither null nor empty");
        }

        /// <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");
        }

        /// <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);
            }
        }

        /// <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.");
        }

图片 8

三.DotNET的Exception类分析:

       
CLR允许非常抛出任何项目的实例,这里我们介绍一个System.Exception类:

     (3).Try-Catch扩展操作:

图片 9

        /// <summary>
        ///     对某对象执行指定功能与后续功能,并处理异常情况
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="source">值</param>
        /// <param name="action">要对值执行的主功能代码</param>
        /// <param name="failureAction">catch中的功能代码</param>
        /// <param name="successAction">主功能代码成功后执行的功能代码</param>
        /// <returns>主功能代码是否顺利执行</returns>
        public static bool TryCatch<T>(this T source, Action<T> action, Action<Exception> failureAction,
            Action<T> successAction) where T : class
        {
            bool result;
            try
            {
                action(source);
                successAction(source);
                result = true;
            }
            catch (Exception obj)
            {
                failureAction(obj);
                result = false;
            }
            return result;
        }

        /// <summary>
        ///     对某对象执行指定功能,并处理异常情况
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="source">值</param>
        /// <param name="action">要对值执行的主功能代码</param>
        /// <param name="failureAction">catch中的功能代码</param>
        /// <returns>主功能代码是否顺利执行</returns>
        public static bool TryCatch<T>(this T source, Action<T> action, Action<Exception> failureAction) where T : class
        {
            return source.TryCatch(action,
                failureAction,
                obj => { });
        }

        /// <summary>
        ///     对某对象执行指定功能,并处理异常情况与返回值
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <typeparam name="TResult">返回值类型</typeparam>
        /// <param name="source">值</param>
        /// <param name="func">要对值执行的主功能代码</param>
        /// <param name="failureAction">catch中的功能代码</param>
        /// <param name="successAction">主功能代码成功后执行的功能代码</param>
        /// <returns>功能代码的返回值,如果出现异常,则返回对象类型的默认值</returns>
        public static TResult TryCatch<T, TResult>(this T source, Func<T, TResult> func, Action<Exception> failureAction,
            Action<T> successAction)
            where T : class
        {
            TResult result;
            try
            {
                var u = func(source);
                successAction(source);
                result = u;
            }
            catch (Exception obj)
            {
                failureAction(obj);
                result = default(TResult);
            }
            return result;
        }

        /// <summary>
        ///     对某对象执行指定功能,并处理异常情况与返回值
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <typeparam name="TResult">返回值类型</typeparam>
        /// <param name="source">值</param>
        /// <param name="func">要对值执行的主功能代码</param>
        /// <param name="failureAction">catch中的功能代码</param>
        /// <returns>功能代码的返回值,如果出现异常,则返回对象类型的默认值</returns>
        public static TResult TryCatch<T, TResult>(this T source, Func<T, TResult> func, Action<Exception> failureAction)
            where T : class
        {
            return source.TryCatch(func,
                failureAction,
                obj => { });
        }

图片 10

   
 本文没有具体介绍try,catch,finally的动,而是受有片于通用的不二法门,主要是形似的开发者对于三只片的采取还来一个认识,就不再做还的牵线。

      1.Message属性:指出抛来特别的缘故。

[__DynamicallyInvokable]
public virtual string Message
{
    [__DynamicallyInvokable]
    get
    {
        if (this._message != null)
        {
            return this._message;
        }
        if (this._className == null)
        {
            this._className = this.GetClassName();
        }
        return Environment.GetRuntimeResourceString("Exception_WasThrown", new object[] { this._className });
    }
}

   
由上述之代码可以看出,Message只具有get属性,所以message是不过念属性。GetClassName()获取很的接近。GetRuntimeResourceString()获取运行时资源字符串。

三.DotNET的Exception类分析:

       
CLR允许老抛出任何类型的实例,这里我们介绍一个System.Exception类:

     2.StackTrace属性:包含抛来十分之前调用了之兼具术的名号和签约。

public static string StackTrace
{
    [SecuritySafeCritical]
    get
    {
        new EnvironmentPermission(PermissionState.Unrestricted).Demand();
        return GetStackTrace(null, true);
    }
}

   
 EnvironmentPermission()用于环境限制,PermissionState.Unrestricted设置权限状态,GetStackTrace()获取堆栈跟踪,具体看一下GetStackTrace()的代码。

internal static string GetStackTrace(Exception e, bool needFileInfo)
{
    StackTrace trace;
    if (e == null)
    {
        trace = new StackTrace(needFileInfo);
    }
    else
    {
        trace = new StackTrace(e, needFileInfo);
    }
    return trace.ToString(StackTrace.TraceFormat.Normal);
}

public StackTrace(Exception e, bool fNeedFileInfo)
{
    if (e == null)
    {
        throw new ArgumentNullException("e");
    }
    this.m_iNumOfFrames = 0;
    this.m_iMethodsToSkip = 0;
    this.CaptureStackTrace(0, fNeedFileInfo, null, e);
}

      以上是取得堆栈跟踪办法的实际实现,此措施要用户调试的时刻。

      1.Message属性:指出抛来很的由。

图片 11

[__DynamicallyInvokable]
public virtual string Message
{
    [__DynamicallyInvokable]
    get
    {
        if (this._message != null)
        {
            return this._message;
        }
        if (this._className == null)
        {
            this._className = this.GetClassName();
        }
        return Environment.GetRuntimeResourceString("Exception_WasThrown", new object[] { this._className });
    }
}

图片 12

   
由以上的代码可以看来,Message只享有get属性,所以message是单纯读属性。GetClassName()获取很的好像。GetRuntimeResourceString()获取运行时资源字符串。

     3.GetBaseException()获取基础十分信息法。

[__DynamicallyInvokable]
public virtual Exception GetBaseException()
{
    Exception innerException = this.InnerException;
    Exception exception2 = this;
    while (innerException != null)
    {
        exception2 = innerException;
        innerException = innerException.InnerException;
    }
    return exception2;
}

 
  InnerException属性是外于十分,这是一个虚方法,在此处吃重写。具体看一下InnerException属性。

[__DynamicallyInvokable]
public Exception InnerException
{
    [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    get
    {
        return this._innerException;
    }
}

     2.StackTrace属性:包含抛来老之前调用了之持有方的名以及签署。

图片 13

public static string StackTrace
{
    [SecuritySafeCritical]
    get
    {
        new EnvironmentPermission(PermissionState.Unrestricted).Demand();
        return GetStackTrace(null, true);
    }
}

图片 14

   
 EnvironmentPermission()用于环境限制,PermissionState.Unrestricted设置权限状态,GetStackTrace()获取堆栈跟踪,具体看一下GetStackTrace()的代码。

图片 15

internal static string GetStackTrace(Exception e, bool needFileInfo)
{
    StackTrace trace;
    if (e == null)
    {
        trace = new StackTrace(needFileInfo);
    }
    else
    {
        trace = new StackTrace(e, needFileInfo);
    }
    return trace.ToString(StackTrace.TraceFormat.Normal);
}

图片 16

图片 17

public StackTrace(Exception e, bool fNeedFileInfo)
{
    if (e == null)
    {
        throw new ArgumentNullException("e");
    }
    this.m_iNumOfFrames = 0;
    this.m_iMethodsToSkip = 0;
    this.CaptureStackTrace(0, fNeedFileInfo, null, e);
}

图片 18

      以上是获取堆栈跟踪办法的有血有肉实现,此道主要用户调试的时。

    4.ToString()将异常信息格式化。

private string ToString(bool needFileLineInfo, bool needMessage)
{
    string className;
    string str = needMessage ? this.Message : null;
    if ((str == null) || (str.Length <= 0))
    {
        className = this.GetClassName();
    }
    else
    {
        className = this.GetClassName() + ": " + str;
    }
    if (this._innerException != null)
    {
        className = className + " ---> " + this._innerException.ToString(needFileLineInfo, needMessage) + Environment.NewLine + "   " + Environment.GetRuntimeResourceString("Exception_EndOfInnerExceptionStack");
    }
    string stackTrace = this.GetStackTrace(needFileLineInfo);
    if (stackTrace != null)
    {
        className = className + Environment.NewLine + stackTrace;
    }
    return className;
}

     在是办法被,将沾之那个信息进行格式化为字符串,this.GetClassName()
获取很类的连带信息。

   
 以上我们注意到[__DynamicallyInvokable]定制性,我们看一下实际的实现代码:

[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public __DynamicallyInvokableAttribute()
{
}

   以上我们任重而道远注释部分,”图像边界“这个特性之连带信息,请参见《Via CLR
c#》,这里虽非做具体的牵线。

     3.GetBaseException()获取基础十分信息法。

图片 19

[__DynamicallyInvokable]
public virtual Exception GetBaseException()
{
    Exception innerException = this.InnerException;
    Exception exception2 = this;
    while (innerException != null)
    {
        exception2 = innerException;
        innerException = innerException.InnerException;
    }
    return exception2;
}

图片 20

 
  InnerException属性是内以死,这是一个虚方法,在此处吃重写。具体看一下InnerException属性。

图片 21

[__DynamicallyInvokable]
public Exception InnerException
{
    [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    get
    {
        return this._innerException;
    }
}

图片 22

四.总结:

 
 以上在对那个的牵线中,主要介绍了CLR的非常处理机制,一些较通用的异常代码,以及对Exception类的介绍。在实际的类型被,我们一般不要以生直白丢弃来为客户,我们于编写程序时,已经考虑次的容错性,在次捕获到很后,尽量错开恢复程序,或者以非常信息写副日志,让程序上错误页。如果出现比较严重的那个,最后将特别抛来,终止程序。

    4.ToString()将十分信息格式化。

图片 23

private string ToString(bool needFileLineInfo, bool needMessage)
{
    string className;
    string str = needMessage ? this.Message : null;
    if ((str == null) || (str.Length <= 0))
    {
        className = this.GetClassName();
    }
    else
    {
        className = this.GetClassName() + ": " + str;
    }
    if (this._innerException != null)
    {
        className = className + " ---> " + this._innerException.ToString(needFileLineInfo, needMessage) + Environment.NewLine + "   " + Environment.GetRuntimeResourceString("Exception_EndOfInnerExceptionStack");
    }
    string stackTrace = this.GetStackTrace(needFileLineInfo);
    if (stackTrace != null)
    {
        className = className + Environment.NewLine + stackTrace;
    }
    return className;
}

图片 24

     在是方法吃,将收获之很信息进行格式化为字符串,this.GetClassName()
获取很类的连带信息。

   
 以上我们注意到[__DynamicallyInvokable]定制性,我们看一下切实可行的实现代码:

[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public __DynamicallyInvokableAttribute()
{
}

   以上我们最主要注释部分,”图像边界“这个特性的连带信息,请参见《Via CLR
c#》,这里就不开具体的牵线。

四.总结:

 
 以上在对大的介绍中,主要介绍了CLR的死去活来处理机制,一些比较通用的非常代码,以及对Exception类的牵线。在实际的项目中,我们一般不要拿好直白抛来受客户,我们在编写程序时,已经考虑次的容错性,在先后捕获到老后,尽量去恢复程序,或者以死信息写副日志,让程序上错误页。如果出现比较严重的那个,最后以异常抛来,终止程序。

原稿链接:http://www.cnblogs.com/pengze0902/p/6185952.html


感谢您的阅读,如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮。本文欢迎各位转载,但是转载文章之后必须在文章页面中给出作者和原文连接。如果需要获取最新的优秀.NET博文,请关注微信公众号“DotNet技术分享”。 

图片 25.jpg)

轻知求真,静心钻研,虚心学习,务实创新,细致温柔。

 

 

标签: c#,
非常处理,
Exception

相关文章