NET非凡管理的思考

   
年关将至,对于大非常多程序猿来讲,霎时就足以闲下来一段时间了,但是在那些闲暇的时日里,只有冲突哪门语言更加好能够消磨时光,估摸近日会有十分的多有关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(); 
            } 
            }

   
 以上的代码只是在证实一种管理格局。应该让抛出的有所极度都沿着方法的调用栈向上传递,并非把她们”吞噬“了后头抛出一个新的可怜。倘诺叁个档期的顺序构造器抛出二个百般,並且该特别未在类型构造器方法中捕获,CL中华V就能够在中间捕获该特别,并改为抛出二个新的TypeInitialztionException。

      4.保持状态:

         
一般景色下,我们完成贰个操作仍然一个办法时,需求调用多少个法子结合产生,在奉行的历程中会出现前面多少个办法成功,前边的法子爆发特别。爆发不可苏醒的非常时回滚部分成功的操作,因为大家必要还原音讯,全体大家在捕获相当时,要求捕获全部的不胜消息。

二.DotNET极度的常用管理机制:

     
在代码发生非常后,大家必要去管理这一个非常,要是三个老大未有获得及时的拍卖,CLCRUISER会终止进度。在老大的管理中,大家得以在二个线程捕获卓殊,在另三个线程中重复抛出特别。卓殊抛出时,CLTiguan会在调用栈中向上查找与抛出的老大类型相配的catch块。若无别的catch块相称抛出的那个类型,就产生一个未处理卓殊。CLENCORE检查评定到进程中的任何线程有叁个位管理特别,都会停止进度。

      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

   
 以上的代码只是在证实一种管理方式。应该让抛出的全部极其都沿着方法的调用栈向上传递,实际不是把他们”吞噬“了之后抛出三个新的那么些。假若贰个种类构造器抛出叁个特别,何况该极度未在品种构造器方法中抓获,CLMurano就可以在里边捕获该特别,并改为抛出二个新的TypeInitialztionException。

     1.卓绝管理块:

     
 (1).try块:富含代码经常需求试行一些通用的能源清理操作,或许供给从那二个中平复,只怕两个都须求。try块还能涵盖只怕会抛出非常的代码。多个try块至少有二个涉嫌的catch块或finall块。 
     

     
 (2).catch块:包涵的是响应一个足够必要施行的代码。catch关键字后的圆括号中的表明式是捕获类型。捕获类型从System.Exception可能其派生类钦定。CLRubicon自上而下搜素三个匹配的catch块,所以应该教具体的那么些放在最上部。一旦CLEnclave找到贰个具备万分捕获类型的catch块,就能够实践内层全体finally块中的代码,”内层finally“是指抛出特别的tey块开头,到特别非凡的catch块之间的保有finally块。

     
 使用System.Exception捕捉非常后,能够应用在catch块的末梢重新抛出特别,因为一旦大家在捕获Exception格外后,未有马上的处理依然终止程序,这一要命或然对程序形成相当的大的安全隐患,Exception类是负有特别的基类,能够捕获程序中存有的可怜,纵然出现十分的大的不得了,我们从没应声的管理,形成的标题是英豪的。

     
 (3).finally块:饱含的代码是保障会实行的代码。finally块的兼具代码实施完结后,线程退出finally块,执行紧跟在finally块之后的言辞。假若不设有finally块,线程将从最终二个catch块之后的讲话发轫实践。

     
备注:格外块能够组合和嵌套,对于四个拾叁分块的样例,在此地就不做牵线,非凡的嵌套可防止止在管理特其他时候重现未管理的卓殊,以上这么些就不再赘述。

二.DotNET分外的常用管理体制:

     
在代码爆发特别后,大家须求去管理这几个特别,假诺三个非常未有获取及时的管理,CL锐界会终止进度。在充裕的拍卖中,我们能够在二个线程捕获相当,在另四个线程中另行抛出非常。至极抛出时,CLENCORE会在调用栈中向上查找与抛出的充足类型相称的catch块。若无另外catch块相配抛出的老大类型,就发出三个未管理分外。CL智跑质量评定到进度中的任何线程有叁个位处理非常,都会停下进度。

    2.可怜处理实例:

     1.万分处理块:

     
 (1).try块:富含代码经常必要实行一些通用的能源清理操作,或许需求从十一分中恢复生机,大概双方都亟需。try块还足以包含恐怕会抛出至极的代码。三个try块至少有一个提到的catch块或finall块。 
     

     
 (2).catch块:包罗的是响应贰个万分需求施行的代码。catch关键字后的圆括号中的表达式是捕获类型。捕获类型从System.Exception也许其派生类钦赐。CL奥迪Q5自上而下搜素一个合营的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类分析:

       
CLRAV4允许极度抛出任何类型的实例,这里大家介绍一个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类分析:

       
CLPAJERO允许特别抛出任何项目的实例,这里我们介绍四个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 CL奇骏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

四.总结:

 
 以上在对丰裕的介绍中,首要介绍了CL本田UR-V的极度管理机制,一些相比较通用的特别代码,以及对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 CL揽胜极光c#》,这里就不做具体的介绍。

四.总结:

 
 以上在对相当的介绍中,首要介绍了CLEvoque的不行管理机制,一些比较通用的可怜代码,以及对Exception类的介绍。在实际的种类中,大家一般不要将特别直白抛出给客户,我们在编写程序时,已经考虑程序的容错性,在先后捕获到极度后,尽量去复苏程序,大概将特别消息写入日志,让程序步向错误页。假诺出现比较严重的格外,最终将十二分抛出,终止程序。

最初的小说链接:http://www.cnblogs.com/pengze0902/p/6185952.html


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

图片 25.jpg)

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

 

 

标签: c#,
特别管理,
Exception