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:
    
  • 相关阅读:
    行定位符、单词定界符实例用法
    什么是正则表达式?
    PHP正则表达式语法汇总
    PDO中的存储过程的详细介绍
    PDO中的事务处理具体介绍
    PDO中错误处理的方法
    PDO中错误处理的方法
    使用默认模式-PDO::ERRMODE_SILENT
    PDO中执行SQL语句的三种方法
    使用默认模式-PDO::ERRMODE_SILENT
  • 原文地址:https://www.cnblogs.com/frogkiller/p/12291485.html
Copyright © 2011-2022 走看看