NET至极处理的考虑

   
年关将至,对于半数以上程序员来说,马上就足以闲下来一段时间了,可是在那个闲暇的日子里,只有冲突哪门语言更好能够消磨时光,估算近年来会有许多关于java与.net的博文出现,笔者表示要作为叁个网络喷子,静静的望着大佬们宣布心绪。

   

    以上的废话说的够多了,那里就不再赘述了,依旧切入宗旨吧。

   
年关将至,对于绝大多数程序员来说,登时就足以闲下来一段时间了,可是在那一个闲暇的年月里,只有争持哪门语言更好能够消磨时光,测度近日会有众多有关java与.net的博文出现,作者表示要作为三个网络喷子,静静的瞅着大佬们宣布心境。

   
在品种耗费中,对于系统和代码的平静和容错性都以有照应的供给。实际开支品种中的代码与样例代码的差别,越多的是在代码的运作的安澜、容错性、扩充性的可比。因为对此贯彻1个效果来说,完毕效益的主干代码是千篇一律的,或者只是在写法上优化而已,不过在落实某3个操作上采取的类来说,那或多或少是多数时候是相同的。那样看来,我们在实际付出的经过中,供给考虑的难题相比多,已经不仅仅局限于某一具体的机能达成,更加多的是代码的安定和扩充性考虑。

    以上的废话说的够多了,那里就不再赘言了,照旧切入核心吧。

   
以上是在其实支付中须求直面包车型客车标题,作者在前不久的博文中,也在设想这么些丰裕到底须求怎么去写,以及卓殊到底必要怎么去领略,在博文中,也有不少的园友对那些的写法和拍卖提议了和睦的看法,在那边笔者就写一下协调的一对通晓,恐怕写的可比浅显和总结,不过只当是一个引子,能够引出大佬们来谈谈本身的其实项目经验。希望对我们有1个救助,也欢迎我们提议本身的想法和见地,分享温馨的学问和看法。

   
在档次费用中,对于系统和代码的一往无前和容错性都是有对应的渴求。实际支出品种中的代码与样例代码的分别,越多的是在代码的运作的祥和、容错性、扩张性的可比。因为对此达成二个功能来说,实现效益的主导代码是同样的,可能只是在写法上优化而已,可是在落到实处某2个操作上采用的类来说,那或多或少是绝大多数时候是一律的。那样看来,大家在事实上开销的长河中,必要考虑的题材相比较多,已经不仅仅局限于某一现实的成效达成,愈来愈多的是代码的安静和扩张性考虑。

一.DotNET不胜的概述:

   
谈到十分,我们就供给驾驭如何叫做非凡,万事万物借使大家想去学习,就应该驾驭大家要读书的事物是何许,那样在心尖同意有八个差不多的咀嚼。万分是指成员没有实现它的名目宣称能够成功的行走。在.NET中,构造器、获取和设置属性、添加和删除事件、调用操作符重载和调用转换操作符等等都不曾办法回到错误代码,不过在那几个组织中又必要告诉错误,那就亟须提供尤其处理机制。

   
在那么些的拍卖中,大家平日选拔到的多少个块分别是:try块;catch块;finally块。那四个块能够同步行使,也足以不写catch块使用,至极处理块可以嵌套使用,具体的办法在底下会介绍到。

   
在13分的拍卖体制中,一般有三种选取:重新抛出一致的百般,向调用栈高级中学一年级层的代码公告该尤其的发出;抛出贰个两样的老大,想调用栈高级中学一年级层代码提供更充分的那1个音讯;让线程从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.从那些中平复:

         
 我们在抓获相当后,能够本着的写一些足够复苏的代码,能够让程序继续运营。在抓获分外时,须要捕获具体的卓殊,丰盛的控制在如何处境下会抛出很是,并驾驭从捕获的尤其类型派生出了那2个类型。除非在catch块的尾声重新抛出11分,不然不要处理或捕获System.Exception非凡。

       2.十三分捕捉需适度:

         
 为何要相宜的捕捉分外呢?如下代码,因为大家不能够怎样格外都去捕捉,在捕获至极后,我们要求去处理这几个非凡,固然大家将持有的12分都捕捉后,然则从未预感会产生的杰出,大家就不曾艺术去处理这几个十分。

       
 若是应用程序代码抛出1个不胜,应用程序的另一端则大概预期要捕捉那一个那三个,因而不能够写成贰个”大小通吃“的不得了块,应该允许该特别在调用栈中向上移动,让应用程序代码针对性地处理这几个充裕。

       
 在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.保持状态:

         
一般情况下,大家做到三个操作依然三个主意时,须要调用多少个点子结合形成,在实施的历程中会出现后边多少个主意成功,后边的点子产生特别。产生不可复苏的百般时回滚部分形成的操作,因为大家必要还原音讯,全数我们在抓获非凡时,需求捕获全数的那1个消息。

       3.从那当中平复:

         
 大家在捕获非常后,能够本着的写一些不行复苏的代码,可以让程序继续运维。在捕获格外时,供给捕获具体的足够,充足的主宰在怎么意况下会抛出至极,并了然从捕获的那个类型派生出了那么些类型。除非在catch块的结尾重新抛出十三分,不然不要处理或捕获System.Exception分外。

      5.隐形实现细节来保险契约:

         
有时恐怕须求捕捉二个不行并再次抛出二个例外的百般,那样可以保障方法的契约,抛出的心格外类型地应当是2个实际的这几个。看如下代码:

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

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

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

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

   
 以上的代码只是在验证一种处理格局。应该让抛出的具有特别都沿着方法的调用栈向上传递,而不是把他们”吞噬“了后头抛出3个新的不胜。假设一个品类构造器抛出二个要命,而且该尤其未在档次构造器方法中抓获,CL福睿斯就会在中间捕获该尤其,并改为抛出2个新的TypeInitialztionException。

      4.保持状态:

         
一般情状下,大家达成一个操作依旧3个办法时,要求调用几个艺术结合形成,在履行的进程中会出现前面几个方法成功,前面包车型客车章程产生分外。产生不可苏醒的那一个时回滚部分形成的操作,因为大家必要苏醒音讯,全数我们在破获格外时,必要捕获全数的不行音讯。

二.DotNET很是的常用处理体制:

     
在代码产生卓殊后,我们须求去处理这些可怜,若是二个可怜没有拿走及时的处理,CLR会终止进度。在老大的拍卖中,大家能够在三个线程捕获格外,在另一个线程中重新抛出特别。分外抛出时,CLSportage会在调用栈中向上查找与抛出的非凡类型匹配的catch块。假诺没有其他catch块匹配抛出的12分类型,就产生八个未处理格外。CL凯雷德检查和测试到进程中的任何线程有贰个位处理分外,都会告一段落进度。

      5.逃匿实现细节来保持契约:

         
有时恐怕需求捕捉3个至极并再一次抛出一个不一的尤其,那样能够维持方法的契约,抛出的心相当类型地应当是3个实际的相当。看如下代码:

图片 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

   
 以上的代码只是在证爱他美(Aptamil)种处理格局。应该让抛出的持有尤其都沿着方法的调用栈向上传递,而不是把她们”吞噬“驾驭后抛出三个新的卓殊。假设一个品类构造器抛出2个尤其,而且该特别未在档次构造器方法中捕获,CL奥迪Q7就会在其间捕获该更加,并改为抛出三个新的TypeInitialztionException。

     1.不胜处理块:

     
 (1).try块:包涵代码常常要求执行一些通用的财富清理操作,大概需求从13分中平复,大概两者都亟待。try块还是能够包罗或许会抛出极度的代码。一个try块至少有二个关联的catch块或finall块。 
     

     
 (2).catch块:包涵的是响应2个丰裕需求实践的代码。catch关键字后的圆括号中的表明式是捕获类型。捕获类型从System.Exception大概其派生类内定。CLLAND自上而下搜素3个郎才女貌的catch块,所以应该教具体的可怜放在顶部。一旦CL奥迪Q5找到三个负有卓殊捕获类型的catch块,就会执行内层全部finally块中的代码,”内层finally“是指抛出十二分的tey块开头,到至极非凡的catch块之间的享有finally块。

     
 使用System.Exception捕捉相当后,能够使用在catch块的末梢重新抛出相当,因为假使大家在捕获Exception分外后,没有及时的处理依然终止程序,这一要命可能对程序造成非常的大的安全隐患,Exception类是负有尤其的基类,能够捕获程序中全部的越发,假设出现较大的十一分,大家并未当即的拍卖,造成的难题是远大的。

     
 (3).finally块:包括的代码是保障会执行的代码。finally块的具有代码执行完成后,线程退出finally块,执行紧跟在finally块之后的口舌。借使不设有finally块,线程将从最终3个catch块之后的言语初叶推行。

     
备注:相当块能够组成和嵌套,对于两个可怜块的样例,在此处就不做牵线,非常的嵌套能够预防在处理格外的时候再一次现身未处理的那么些,以上那些就不再赘言。

二.DotNET卓殊的常用处理机制:

     
在代码产生至极后,大家需求去处理那些那几个,假若2个相当没有获得及时的拍卖,CL奥德赛会终止进程。在特其他处理中,我们得以在贰个线程捕获十分,在另二个线程中重新抛出11分。至极抛出时,CL宝马7系会在调用栈中向上查找与抛出的不得了类型匹配的catch块。假若没有其他catch块匹配抛出的万分类型,就发生贰个未处理极度。CLEscort检查和测试到进程中的任何线程有三个位处理格外,都会终止进度。

    2.万分处理实例:

     1.10分处理块:

     
 (1).try块:包蕴代码常常须求进行一些通用的能源清理操作,大概须求从这一个中平复,大概两者都须求。try块还是能够分包可能会抛出非凡的代码。三个try块至少有3个事关的catch块或finall块。 
     

     
 (2).catch块:包括的是响应一个百般须要实施的代码。catch关键字后的圆括号中的表明式是捕获类型。捕获类型从System.Exception或许其派生类内定。CL福睿斯自上而下搜素二个同盟的catch块,所以理应教具体的至极放在顶部。一旦CL智跑找到几个兼有卓殊捕获类型的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类分析:

       
CLCR-V允许相当抛出任何类型的实例,那里大家介绍二个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的选用,而是交由一些相比较通用的措施,首假若相似的开发者对于八个块的运用都有3个认识,就不再做重新的牵线。

      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类分析:

       
CLOdyssey允许万分抛出任何项指标实例,那里我们介绍二个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 CLQX56c#》,这里就不抓牢际的牵线。

     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

四.总结:

 
 以上在对格外的介绍中,重要介绍了CL凯雷德的卓殊处理机制,一些相比较通用的尤其代码,以及对Exception类的牵线。在实际的门类中,大家一般不要将11分直白抛出给客户,大家在编写程序时,已经考虑程序的容错性,在先后捕获到分外后,尽量去苏醒程序,恐怕将非凡消息写入日志,让程序进入错误页。固然现身比较严重的不行,最终将拾贰分抛出,终止程序。

    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 CL酷威c#》,那里就不做具体的介绍。

四.总结:

 
 以上在对那多少个的牵线中,首要介绍了CLRubicon的尤其处理体制,一些较为通用的十二分代码,以及对Exception类的介绍。在实际上的品类中,我们一般不要将那些直白抛出给客户,大家在编写程序时,已经考虑程序的容错性,在先后捕获到十分后,尽量去复苏程序,只怕将尤其新闻写入日志,让程序进入错误页。假诺出现相比严重的那么些,最终将拾壹分抛出,终止程序。

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


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

图片 25.jpg)

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

 

 

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

相关文章

admin

网站地图xml地图