zoukankan      html  css  js  c++  java
  • 自定义异常类

        FCL定义的系统异常不能解决所有问题,在实际项目中,我们通常要根据自己的需要定义自己的异常类,以便于我们能够更好地捕获异常信息。接下来我将自己定义的异常类一步步贴上来,供彼此交流,学习,不当之处还望指正。

    (1)定义异常类MyException,该类继承于Exception,实现了ISerializable接口。代码如下:

    View Code
    1 //Serializable指定了自定义异常类可以被序列化
    2   [Serializable]
    3 public class MyException : Exception, ISerializable
    4 {
    5 //自定义本地文本信息
    6   private string myMsg;
    7
    8 public string MyMsg
    9 {
    10 get
    11 {
    12 return myMsg;
    13 }
    14 }
    15 //重写只读本地文本信息属性
    16 public override string Message
    17 {
    18 get
    19 {
    20 string msgBase = base.Message;
    21 return myMsg == null ? msgBase : msgBase + myMsg;
    22 }
    23 }
    24 //实现基类的各公有构造函数
    25 public MyException()
    26 : base()
    27 {
    28 }
    29 public MyException(string message)
    30 : base(message)
    31 {
    32 }
    33 public MyException(string message, Exception innerException)
    34 : base(message, innerException)
    35 {
    36 }
    37
    38 //为新增字段实现构造函数
    39 public MyException(string message, string myMsg)
    40 : this(message)
    41 {
    42 }
    43 public MyException(string message, string myMsg, Exception innerException)
    44 : this(message, innerException)
    45 {
    46 this.myMsg = myMsg;
    47 }
    48 //用于序列化的构造函数,以支持跨应用程序域或远程边界的封送处理
    49 public MyException(SerializationInfo info, StreamingContext context)
    50 : base(info, context)
    51 {
    52 }
    53 //重写基类GetObjectData()方法,实现向SerializationInfo中添加自定义字段信息
    54 public override void GetObjectData(SerializationInfo info, StreamingContext context)
    55 {
    56 info.AddValue("MyMsg", myMsg);
    57 base.GetObjectData(info, context);
    58 }
    59 }

    (2)声明一个额外的类,用于测试自定义的异常类,代码如下

    1 class TestMyException
    2 {
    3 //函数只接受1到100的数字,如若不在此范围,则抛出自定义的异常
    4   public void Set(int i)
    5 {
    6 //若输入的数字大于100
    7   if (i > 100)
    8 {
    9 //初始化一个自定义异常类MyException
    10 MyException e = new MyException("这是自定义异常类抛出的信息:输入的数字超过100了,请小点!", "这是系统抛出的异常信息");
    11 // e 首先进行了Data和HelpLink属性的初始化,这两个属性都是继承于Exception
    12 e.Data.Add("MY", "自定义的异常");
    13 e.Data.Add("Time", DateTime.Now);
    14 e.HelpLink = "http://www.baidu.com";
    15 throw e;
    16 }
    17 else if (i < 1)
    18 {
    19 MyException e = new MyException("这是自定义异常类抛出的信息:输入的数字不足1,请大点!", "这一部分是系统抛出的异常信息");
    20 e.Data.Add("MY", "自定义的异常");
    21 e.Data.Add("Time", DateTime.Now);
    22 e.HelpLink = "http://www.baidu.com";
    23 throw e;
    24 }
    25 //输入的数字在1-100之间
    26 Console.WriteLine("输入的数字“{0}”在范围(1~100)内。",i);
    27 }
    28 }

    (3)客户端代码:

    View Code
    1 class Program
    2 {
    3 static void Main(string[] args)
    4 {
    5 Console.WriteLine("Please input a numeral!");
    6 try
    7 {
    8 //接收输入的数字并转化为int型,若输入为字符,会抛出系统自带的异常"Input string was not in current format"
    9 int input = Convert.ToInt32(Console.ReadLine());
    10 TestMyException tst = new TestMyException();
    11 tst.Set(input);
    12 Console.WriteLine("通过测试,没抛出异常");
    13 }
    14 //多个catch块在一起的时候,编译器uaoqiu将特定程度较高的异常放在最前边,而程度不高的异常类放在后边
    15 //也就是说在异常类的继承机构中,把最底层的类例如System.Exception放在最后一个catch块中,而教高层的类放在最前边。
    16 //刚好跟异常类的”树形“成倒状
    17 catch (MyException ex)
    18 {
    19 Console.WriteLine("输入的数字不在1到100以内,故抛出自定义异常");
    20 Console.WriteLine("异常信息:{0}", ex.Message);
    21 Console.WriteLine("发生时间:{0}", ex.Data["Time"]);
    22 Console.WriteLine("更多帮助:{0}", ex.HelpLink);
    23 }
    24 catch (Exception ex)
    25 {
    26 Console.WriteLine("系统异常信息:{0}", ex.Message);
    27 }
    28 Console.ReadLine();
    29 }
    30 }
    运行结果为:
    (1)若输入的数字在1-100之间,则不让其抛出异常,运行效果如图(1)
    1
    (2)若输入的数字大于100,抛出异常,过大,运行效果如图(2)
    2
    (3)若输入的数字小于1,抛出异常,过小,运行效果如图(3)
    3
     
    最后小结一下自定义异常类需要注意的地方:

    1 选择合适的基类继承,一般情况下我们选择Exception或者其派生类作为自定义异常类的基类。

    2 System.Exception提供了三个构造函数,一般情况下,在自定义的异常类中也应该实现这三个构造函数,并且最好调用其基类中相应的构造函数,如果自定义类中还有新的字段要处理,则应该为新的字段实现新的构造函数来实现

    3 所有的异常类型都是可序列化的,因此必须为自定义异常类添加SerializableAttribute特性,并实现ISerializable接口

    4 以Exception作为自定义异常类的类名的后缀,良好的编程习惯

    5 在自定义异常类中包括本地化描述信息,也就说实现异常类的Message属性,而不是从基类继承Message。

     
  • 相关阅读:
    C语言探索之旅 | 第二部分第二课:进击的指针,C语言的王牌!
    C语言探索之旅 | 第二部分第一课:模块化编程
    C语言探索之旅 | 第一部分练习题
    C语言探索之旅 | 第一部分第十一课:函数
    数据结构和算法 | 第一部分第五课:算法复杂度实践
    数据结构和算法 | 第一部分第四课:算法复杂度(下)
    数据结构和算法 | 第一部分第三课:算法复杂度(上)
    数据结构和算法 | 第一部分第二课:小鸭子们去旅行
    数据结构和算法 | 第一部分第一课:什么是数据结构和算法
    C语言探索之旅 | 第一部分第十课:第一个C语言小游戏
  • 原文地址:https://www.cnblogs.com/liujb/p/2068695.html
Copyright © 2011-2022 走看看