专栏首页.Net、.Net Core 、Docker.NET----错误和异常处理机制

.NET----错误和异常处理机制

前言

  错误的出现并不总是编写程序的人的原因,有时应用程序会因为应用程序的最终用户引发的动作或运行代码的环境发生错误。无论如何,我们都应预测应用程序中出现的错误,并相应的进行编码。

  .Net改进了处理错误的方式。C#处理错误的机制可以为每种错误提供自定义处理方式,并把识别错误的代码与处理错误的代码分别开来。

异常类

  在C#中当出现某个特殊的异常错误条件时,就会创建抛出一个异常对象,这个对象包含有助于跟踪问题的信息。.Net提供了许多预定义的异常类,我们下面看看一些常见特别的异常类吧(异常类太多了,这里就介绍几个常见的)。

  对于.Net类,一般的异常类System.Exception派生自System.Object,通常不在代码中抛出System.Exception泛型对象,因为他们无法确定错误情况的本质。

  在该层次中有两个重要的类,他们派生自System.Exception类:

    • SystemException------该类用于通常由.NET允许库抛出的异常,或者由几乎所有的应用程序抛出的异常。例如,如果.NET运行库检测到栈已满,他就会抛出StackOverflowException异常。另一方面,如果检测到调用方法时参数不对,就可以在自己的代码中选择抛出ArgumentException异常或其子类。SystemException异常的子类包括表示致命错误和非致命错误的异常。
    • ApplicationException----在.NET Framework最初的设计中,是打算把这个类作为自定义应用程序异常类的基类的。不过,CLR抛出的一些异常类也派生自这个类。应用程序抛出的异常则派生自SystemException。因此从ApplicationException派生自自定义异常类型没有任何好处,取而代之的是,可以直接从Exception基类派生自定义异常类。

  其他可能会用到的异常类包括:

    • StackOverflowException-------如果分配给栈的内存区域已满,就会抛出这个异常。如果一个方法连续地递归调用自己,就可能发生栈溢出。这一般是一个致命错误,因为它禁止应用程序执行除了中断以外的其他任务。在这种情况下,甚至也不可能执行到finally块。通常用户自己不能处理像这样的错误,而应退出应用程序。
    • EndOfStreamException-------这个异常通常是因为读到文件末尾而抛出的,流表示数据源之间的数据流。
    • OverflowException-----如果要在checked上下文中把包含-40的int类型数据强制转换为uint数据,就会抛出这个异常
    • MemberAccessException----------该类用于处理访问类的成员失败时所引发的异常。失败的原因可能的原因是没有足够的访问权限,也可能是要访问的成员根本不存在(类与类之间调用时常用)
    • IndexOutOfException-------该类用于处理下标超出了数组长度所引发的异常

使用try...catch...finally捕获异常

  • try 块包含的代码组成了程序的正常操作部分,但这部分程序可能会遇到某些严重的错误。
  • catch块包含的代码处理各种错误,这些错误是执行try块中的代码时遇到的问题。这个快可以用来记录错误。
  • finally快包含的代码清理资源或执行通常要在try块或者catch块末尾执行的其他操作。无论是否抛出异常,都会执行finally块。finally块中防止return语句,编译器会标记一个错误。另外此块可以如果没有需要关闭或者处理的其他操作可以省略此块。

  异常处理具有性能含义,在常见的情况下,不应该使用异常处理错误。应尽量编写好避免错误出现的代码。

  在异常捕获中,我们可以实现多个catch块来针对不同的错误做出对应的错误处理。下面我们看一个例子:

class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                try
                {
                    string userInput;
                    Console.WriteLine("请输入0-5之间任意一个数字:");
                    userInput = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(userInput))
                    {
                        break;
                    }


                    if (int.TryParse(userInput, out int index))
                    {
                        if (index < 0 || index > 5)
                        {

                            throw new IndexOutOfRangeException($"你输入的数字是{index}");

                        }
                        Console.WriteLine($"你输入的数字是{index}");
                    }
                    else
                    {
                        throw new Exception("请输入数字");
                    }
                }
                catch (IndexOutOfRangeException ex)
                {
                    Console.WriteLine($"你输入的数字不在此范围内.{ex.Message}");
                }
                catch (Exception ex)
                {

                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    Console.WriteLine("谢谢合作");
                }

               
            }
        }
    }

  在此事例中,定义了两个catch块。如果输入的超过规定返回的数字,则会抛出超出范围的错误也就进入对应的catch块。而输入的非数字也就进入了另外一个catch块进行处理。

  下面我们看一看关于System.Exception属性。熟悉了解其中熟悉能更好的去观察理解抛出的异常错误。

过滤异常、创建用户定义的异常

  自从C#6开始就支持异常过滤器。Catch块仅在过滤器但会true时执行。捕获不同的异常类型时,可以有行为不同的代码块。在某些情况下,catch块基于异常的内容执行不同的操作。下面我们看下如何来使用异常过滤器吧:

 public class MyIndexOutOfException :SystemException
    {
        public MyIndexOutOfException(string message) : base(message)
        {

        }

        public int ErrorCode { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                int steInput = 12;

                if (steInput > 10)
                {
                    throw new MyIndexOutOfException("数据超出了范围") { ErrorCode = 1 };
                }

            }

            catch (MyIndexOutOfException ex) when (ex.ErrorCode!=1)

            {
                Console.WriteLine("出现了自定义错误");
            }

            catch (MyIndexOutOfException ex) when (ex.ErrorCode == 1)
            {
                Console.WriteLine(ex.Message);
            }

            catch (Exception ex)
            {

                throw;
            }
        }
    }

  上面例子中,自定义了一个异常处理,同时增加ErrorCode,以此来作为过滤条件,利用关键字When+条件来进行过滤。

总结

  本篇文章介绍了异常处理错误的情况及机制,我们不仅可以输出代码好难过的一般错误代码,也可以输出我们自己定义的特殊错误情况。无论编程技术有多好,程序都必须能处理可能出现的任何错误。对不同的错误采取相应的应对措施,才是正确编码的其中一步。

不是井里没有水,而是你挖的不够深。不是成功来得慢,而是你努力的不够多。


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 通俗易懂设计模式解析——外观模式

      今天一起来看看外观模式,外观模式也是我们介绍的结构型设计模式的第五个模式了。外观外表,有句话是这么说的人靠衣装 佛靠金装。打扮的好,整理的好。外观靠上去整整...

    小世界的野孩子
  • Linux+.Net Core+Nginx(在Linux上使用Nginx反向代理.Net Core 项目)

    之前的文章中有提到关于使用Nginx在linux来实现反向代理,今天我们继续加点料。在Centos7中部署.NetCore,然后使用Nginx进行反向代理!

    小世界的野孩子
  • 通俗易懂设计模式解析——备忘录模式

      今天我们来看看备忘录模式【MementoPattern】,我们平时写文档的时候一不小心写错了一些字或者删除了一些东西怎么办呢?不用怕、Windows里面提供...

    小世界的野孩子
  • 微信XML消息model定义之微信公众平台(一)

    lpe234
  • 2019-1-2-使用AggregateException的Handle过滤指定异常

    在一些并行操作或者任务列表执行的过程中,会需要用到AggregateException进行聚合异常的处理

    黄腾霄
  • 语音识别开源工具PyTorch-Kaldi:兼顾Kaldi效率与PyTorch灵活性

    杰出的科学家和工程师们一直在努力地给机器赋予自然交流的能力,语音识别就是其中的一个重要环节。人类对语音识别技术的研究从上世纪 50 年代开始就未曾停止。在长期的...

    机器之心
  • Swagger笔记(二)springboot集成和ApiModel使用不当的一个小问题

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    yingzi_code
  • 2020-08-19:TCP是通过什么机制保障可靠性的?

    福哥口诀法:校(jiao)序确重拥流连(tcp可靠性保障机制:校验、序号、确认、重传、拥塞、流量、连接)

    福大大架构师每日一题
  • 剑指offer No.29 最小的k个数

    输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。

    week
  • mybatis文件映射之鉴别器discriminator标签

    说明:distriminator中的javaType指定数据库中字段对应着java中的属性的类型,column属性为列名称。case标签中value属性标识数据...

    绝命生

扫码关注云+社区

领取腾讯云代金券