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

   
 以上的代码只是在验证一种管理格局。应该让抛出的装有特别都沿着方法的调用栈向上传递,并不是把她们”吞噬“了后头抛出三个新的不得了。如若一个系列构造器抛出多少个可怜,况兼该极其未在品种构造器方法中抓获,CLENVISION就能在中间捕获该极度,并改为抛出一个新的TypeInitialztionException。

      4.保险状态:

         
一般情况下,大家成功一个操作照旧贰个主意时,须求调用几个议程结合产生,在试行的经过中会出现前边多少个艺术成功,前面包车型客车艺术发生特别。发生不可恢复生机的十分时回滚部分成功的操作,因为大家须要还原新闻,全体大家在破获非凡时,须要捕获全部的格外音讯。

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

     
在代码发生卓殊后,大家供给去管理那么些那些,假若四个可怜未有获取及时的拍卖,CLENVISION会终止进度。在拾叁分的管理中,大家能够在三个线程捕获分外,在另贰个线程中重新抛出十分。非常抛出时,CLRAV4会在调用栈中向上查找与抛出的百般类型匹配的catch块。若无任何catch块相配抛出的老大类型,就产生二个未管理万分。CLCRUISER检查测验到进程中的任何线程有贰个位管理极其,都会截止进度。

      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

   
 以上的代码只是在认证一种管理格局。应该让抛出的具有特别都沿着方法的调用栈向上传递,并不是把她们”吞噬“了后来抛出一个新的极度。假若三个档期的顺序构造器抛出四个特别,何况该特别未在类型构造器方法中捕获,CLSportage就能够在当中捕获该特别,并改为抛出一个新的TypeInitialztionException。

     1.相当处理块:

     
 (1).try块:包罗代码平时必要实施一些通用的能源清理操作,或许供给从这个中平复,或然双方都须要。try块还是能分包恐怕会抛出相当的代码。四个try块至少有三个事关的catch块或finall块。 
     

     
 (2).catch块:包涵的是响应一个百般要求施行的代码。catch关键字后的圆括号中的表达式是捕获类型。捕获类型从System.Exception只怕其派生类钦定。CLENVISION自上而下搜素一个同盟的catch块,所以理应教具体的格外放在顶上部分。一旦CL奥迪TT RS找到二个有所特别捕获类型的catch块,就能够试行内层全部finally块中的代码,”内层finally“是指抛出极其的tey块起始,到十二分十分的catch块之间的有着finally块。

     
 使用System.Exception捕捉至极后,能够行使在catch块的最后重新抛出极度,因为一旦我们在捕获Exception非常后,未有登时的管理依然终止程序,这一这多少个或许对程序形成非常大的安全隐患,Exception类是怀有特别的基类,可以捕获程序中具有的百般,就算出现非常大的充裕,我们未有即时的拍卖,变成的主题素材是伟大的。

     
 (3).finally块:满含的代码是保障会实行的代码。finally块的持有代码实践完成后,线程退出finally块,奉行紧跟在finally块之后的说话。假诺不设有finally块,线程将从最终三个catch块之后的话语开端实行。

     
备注:万分块能够结合和嵌套,对于多少个极度块的样例,在那边就不做牵线,相当的嵌套能够堤防在管理极度的时候再现未处理的可怜,以上这一个就不再赘言。

二.DotNET非凡的常用管理机制:

     
在代码爆发至极后,我们需求去管理这些可怜,倘使一个特别未有博得及时的拍卖,CLLAND会终止进程。在丰盛的拍卖中,大家得以在一个线程捕获相当,在另二个线程中另行抛出拾叁分。非凡抛出时,CLKuga会在调用栈中向上查找与抛出的极其类型相称的catch块。若无其他catch块相称抛出的十三分类型,就生出贰个未处理格外。CL奥迪Q7检验到进度中的任何线程有八个位处理特别,都会结束进度。

    2.非常管理实例:

     1.相当管理块:

     
 (1).try块:包蕴代码日常需求实践一些通用的能源清理操作,恐怕需求从这一个中平复,只怕双方都须要。try块还足以分包可能会抛出极其的代码。三个try块至少有一个关乎的catch块或finall块。 
     

     
 (2).catch块:包涵的是响应多个卓绝供给实行的代码。catch关键字后的圆括号中的表明式是捕获类型。捕获类型从System.Exception可能其派生类钦命。CL奥迪Q5自上而下搜素多少个相称的catch块,所以应当教具体的那么些放在最上端。一旦CL奥迪Q5找到三个具备格外捕获类型的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类分析:

       
CLLX570允许极其抛出任何项目标实例,这里大家介绍二个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类分析:

       
CL瑞虎允许特别抛出任何项目标实例,这里大家介绍二个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 CLLX570c#》,这里就不抓牢际的介绍。

     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奔驰G级的特别管理体制,一些比较通用的格外代码,以及对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 CLRubiconc#》,这里就不抓好际的介绍。

四.总结:

 
 以上在对丰硕的介绍中,重要介绍了CL奇骏的那多少个管理机制,一些较为通用的要命代码,以及对Exception类的介绍。在实际上的连串中,大家一般不要将不胜直白抛出给客户,大家在编写程序时,已经思量程序的容错性,在先后捕获到不行后,尽量去恢复生机程序,可能将非常新闻写入日志,让程序步向错误页。要是出现相比较严重的特别,最终将非常抛出,终止程序。

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


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

图片 25.jpg)

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

 

 

标签: c#,
卓殊管理,
Exception