zoukankan      html  css  js  c++  java
  • clr via c# 异常和状态管理

    1,System.Exception 类---所有异常类的基类

    Message

    readonly string 指出异常的原因
    Data readonly IDictionary 引用一个键值对集合
    Source r/w string 包含异常的程序集名称
    StackTrace r string 包含异常之前调用所有方法和信息
    TargetSite r MethodBase 包含抛出异常的方法
    InnerException r Exception

    如果当前异常时在处理一个异常时抛出的,则指出上个异常是什么

    可以使用Exception.GetBaseException来遍历异常链表.

    HResult r/w int COM api 返回值维护.

    1.1    Exception.GetBaseException 方法用法

    •         首先创建两个异常类用于重新抛出:
    class SecondLevelException : Exception
        {
            public SecondLevelException(string message, Exception inner)//使用Message和InnerExciption来初始化异常
                : base(message, inner)
            { }
        }
        class ThirdLevelException : Exception//使用Message和InnerExciption来初始化异常
        {
            public ThirdLevelException(string message, Exception inner)
                : base(message, inner)
            { }
        }
      
    •       其次,创建用于抛出异常的行为方法:
      • static void DivideBy0()
                {
                    try
                    {
                        int zero = 0;
                        int ecks = 1 / zero;
                    }
                    catch (Exception ex)
                    {
                        throw new SecondLevelException(
                            "Forced a division by 0 and threw " +
                            "a second exception.", ex);
                    }
                }
        static void Rethrow()
                {
                    try
                    {
                        DivideBy0();
                    }
                    catch (Exception ex)
                    {
                        throw new ThirdLevelException(
                            "Caught the second exception and " +
                            "threw a third in response.", ex);
                    }
                }
    •     创建测试方法:
      •  public static void Go()
                {
        
        
                    try
                    {
                        // This function calls another that forces a 
                        // division by 0.
                        Rethrow();
                    }
                    catch (Exception ex)
                    {
                        Exception current;
        
        
                        // This code unwinds the nested exceptions using the 
                        // InnerException property.
                        current = ex;
                        while (current != null)
                        {
                            Console.WriteLine(current.ToString());
                            Console.WriteLine();
                            current = current.InnerException;//调用当前异常的上个异常.
                        }
        
                        // Display the innermost exception.
                        Console.WriteLine(
                            "Display the base exception " +
                            "using the GetBaseException method:
        ");
                        Console.WriteLine(
                            ex.GetBaseException().ToString());
                    }
                }


    • 给出测试结果
    • ClrFromCSharp_2_2.LearnException.ThirdLevelException: Caught the second exception and threw a third in response. ---> ClrFromCSharp_2_2.LearnException.SecondLevelException: Forced a division by 0 and threw a second exception. ---> System.DivideByZeroException: 尝试除以零。
         在 ClrFromCSharp_2_2.LearnException.ExceptionRef.DivideBy0() 位置 C:
      epsClrFromCSharpClrFromCSharp_2_2LearnExceptionExceptionRef.cs:行号 62
         --- 内部异常堆栈跟踪的结尾 ---
         在 ClrFromCSharp_2_2.LearnException.ExceptionRef.DivideBy0() 位置 C:
      epsClrFromCSharpClrFromCSharp_2_2LearnExceptionExceptionRef.cs:行号 66
         在 ClrFromCSharp_2_2.LearnException.ExceptionRef.Rethrow() 位置 C:
      epsClrFromCSharpClrFromCSharp_2_2LearnExceptionExceptionRef.cs:行号 48
         --- 内部异常堆栈跟踪的结尾 ---
         在 ClrFromCSharp_2_2.LearnException.ExceptionRef.Rethrow() 位置 C:
      epsClrFromCSharpClrFromCSharp_2_2LearnExceptionExceptionRef.cs:行号 52
         在 ClrFromCSharp_2_2.LearnException.ExceptionRef.Go() 位置 C:
      epsClrFromCSharpClrFromCSharp_2_2LearnExceptionExceptionRef.cs:行号 19---从最初异常---至抛出异常的一个trace.
      
      ClrFromCSharp_2_2.LearnException.SecondLevelException: Forced a division by 0 and threw a second exception. ---> System.DivideByZeroException: 尝试除以零。
         在 ClrFromCSharp_2_2.LearnException.ExceptionRef.DivideBy0() 位置 C:
      epsClrFromCSharpClrFromCSharp_2_2LearnExceptionExceptionRef.cs:行号 62
         --- 内部异常堆栈跟踪的结尾 ---
         在 ClrFromCSharp_2_2.LearnException.ExceptionRef.DivideBy0() 位置 C:
      epsClrFromCSharpClrFromCSharp_2_2LearnExceptionExceptionRef.cs:行号 66
         在 ClrFromCSharp_2_2.LearnException.ExceptionRef.Rethrow() 位置 C:
      epsClrFromCSharpClrFromCSharp_2_2LearnExceptionExceptionRef.cs:行号 48//从最初异常到抛出异常的一个base.
      
      System.DivideByZeroException: 尝试除以零。
         在 ClrFromCSharp_2_2.LearnException.ExceptionRef.DivideBy0() 位置 C:
      epsClrFromCSharpClrFromCSharp_2_2LearnExceptionExceptionRef.cs:行号 62//从最初异常到抛出异常的一个base.
      
      Display the base exception using the GetBaseException method:
      
      System.DivideByZeroException: 尝试除以零。
         在 ClrFromCSharp_2_2.LearnException.ExceptionRef.DivideBy0() 位置 C:
      epsClrFromCSharpClrFromCSharp_2_2LearnExceptionExceptionRef.cs:行号 62//最底层的一个ex
      • 由此我们可以看出,InnerException,是通过Throw方法在Catch块中传递的.类似
      • static void Rethrow()
                {
                    try
                    {
                        DivideBy0();
                    }
                    catch (Exception ex)
                    {
                        throw new ThirdLevelException(
                            "Caught the second exception and " +
                            "threw a third in response.", ex);
                    }
                }
      • Exception.GetBaseException
      • ex.GetBaseException().ToString());//获取Exception链表的最先抛出的异常.越后面抛出的越前面.
      • 定义最先抛出的异常---最Base,最底部;最后抛出的异常---Current,最顶部.

    2,自定义异常类及其使用方法:

    1.            定义一个自定义的异常类


    [Serializable]
        public sealed class Exception<TExceptionArgs> : Exception, ISerializable where TExceptionArgs:ExceptionArgs
        {
            private const string c_args = "args";
            private readonly TExceptionArgs m_args;
            public TExceptionArgs Args { get { return m_args; } }
            public Exception(string message=null,Exception innerException = null) : this(null, message, innerException) { }
            public Exception(TExceptionArgs args,string message=null,Exception innerException = null) : base(message, innerException) { m_args = args; }
            //这个构造器用于反序列化,由于类私有的,所以构造器是私有的.
            [SecurityPermission(SecurityAction.LinkDemand,Flags=SecurityPermissionFlag.SerializationFormatter)]//给该类保护
            private Exception(SerializationInfo info,StreamingContext context):base(info,context)
            {
                m_args = (TExceptionArgs)info.GetValue(c_args, typeof(TExceptionArgs));
            }
            [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
            public override void GetObjectData(SerializationInfo info,StreamingContext context)
            {
                info.AddValue(c_args, m_args);
                base.GetObjectData(info, context);
            }
            public override string Message
            {
                get
                {
                    string baseMsg = base.Message;
                    return (m_args == null) ? baseMsg : string.Format("{0} ({1})", baseMsg, m_args.Message);
                }
            }
            public override bool Equals(object obj)
            {
                Exception<TExceptionArgs> other = obj as Exception<TExceptionArgs>;
                if (other == null) return false;
                return object.Equals(m_args, other.m_args) && base.Equals(obj);
            }
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
        }
    1. 该异常类继承了Exception和Iserializable.并且实现了类的序列化和反序列化
    2. 该类可以携带一个参数类信息.
    [Serializable]
        public abstract class ExceptionArgs
        {
            public virtual String Message { get { return string.Empty; } }
        }


    3,建立自己的ExceptionArgs的派生类,用于携带异常信息.

    public sealed class DiskFullExceptionArgs : ExceptionArgs
        {
            public string Path { get; }
            public DiskFullExceptionArgs(string path)
            {
                Path = path;
            }
            public override string Message => Path ?? base.Message;
        }

        4,使用方法:

     public static void GoCustomException()
            {
                try
                {
                    throw new Exception<DiskFullExceptionArgs>(new DiskFullExceptionArgs(@"c:"), "disk is full");
                }
                catch(Exception<DiskFullExceptionArgs> e)
                {
                    Console.WriteLine("the Exception Message is {0}", e.Message);//调用类e.Message
                    Console.WriteLine("the ExceptionArgs Message is {0}", e.Args.Message);//调用类e.Args.Message
                }
            }

         5,结果

    the Exception Message is disk is full (c:)
    the ExceptionArgs Message is c:
    
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 交换Easy
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法训练 矩阵乘方
    QT中给各控件增加背景图片(可缩放可旋转)的几种方法
    回调函数实现类似QT中信号机制
    std::string的Copy-on-Write:不如想象中美好(VC不使用这种方式,而使用对小字符串更友好的SSO实现)
  • 原文地址:https://www.cnblogs.com/frogkiller/p/12291485.html
Copyright © 2011-2022 走看看