C#异常处理

C#中异常处理一般不影响性能,所以应该返回必要的错误码或者打印Log以外,需要的地方必须加入异常处理

一、.net异常处理和预定义异常类

.net内建异常类有:
System.SystemException .net CRL抛出的严重异常,例如抛出StackOverflowException,ArgumentException
System.ApplicationException  应用程序的异常,自定义了应用程序异常应该继承该类。
EndOfStreamException 这个异常通常是因为读到文件末尾而抛出的。
OverflowException  如果再checked环境下转换类型溢出就会抛出这个异常。
FormatException 格式转换异常,例如a转换为数字。
Exception 异常的基类,可以获取到所有没有预料到的异常;可以用它的Message属性获取异常详细信息。

异常处理执行逻辑:
// 用try避免没有导致程序崩溃
try
{
  if(xxx)
 throw new xxx; // 不抛出,而是由基类库中抛出是非常常见的。后面代码不再执行,跳转到catch块
}
// 出现了异常在这里处理
catch(CExceptionClass e)
{
}
// 无论如何都执行
finally
{
}
.net会将异常部分代码用一个更大的try块和catch块来处理,如果程序中没有catch处理异常,那么程序将会抛出异常而终止,并且系统提示异常信息。
所以如果是应用程序应该处理尽可能出现的异常,如果是库那么最好不要抛出自定义异常但但抛出.net预定义异常类。
实例:

using System;

namespace Wrox.ProCSharp.AdvancedCSharp
{
   public class MainEntryPoint
   {
      public static void Main()
      {
          while ( true )
         {
            try
            {
               Console.Write("Input a number between 0 and 5 " + 
                  "(or just hit return to exit)> ");
               string userInput = Console.ReadLine();
               if (userInput == "")
                  break;
               int index = Convert.ToInt32(userInput);
               if (index < 0 || index > 5)
                  throw new IndexOutOfRangeException(
                     "You typed in " + userInput);
                Console.WriteLine("Your number was " + index);
            }
            catch (IndexOutOfRangeException e)
            {
               Console.WriteLine("Exception: " + 
                  "Number should be between 0 and 5. " + e.Message);
            }            
            catch (Exception e)
            {
               Console.WriteLine(
                  "An exception was thrown. Message was: " + e.Message);
            }
            catch
            {
               Console.WriteLine("Some other exception has occurred");
            }
            finally
            {
               Console.WriteLine("Thank you");
            }
         }
      }
   }
}

二、自定义异常类型

自定义异常类继承  ApplicationException类,提供构造函数和输出信息。
在使用try{}catch(){}finally块中嵌套的抛出和处理异常即可。
using System;
using System.IO;

namespace Wrox.ProCSharp.AdvancedCSharp
{
   class MainEntryPoint
   {
      static void Main()
      {
          Console.Write("Please type in the name of the file " +
            "containing the names of the people to be cold-called > ");
         string fileName = Console.ReadLine();
         ColdCallFileReader peopleToRing = new ColdCallFileReader();

         try
         {
            peopleToRing.Open(fileName);
            for (int i=0 ; i<peopleToRing.NPeopleToRing; i++)
            {
               peopleToRing.ProcessNextPerson();
            }
            Console.WriteLine("All callees processed correctly");
         }
         catch(FileNotFoundException)
         {
            Console.WriteLine("The file {0} does not exist", fileName);
         }
         catch(ColdCallFileFormatException e)
         {
            Console.WriteLine(
          "The file {0} appears to have been corrupted", fileName);
            Console.WriteLine("Details of problem are: {0}", e.Message);
            if (e.InnerException != null)
               Console.WriteLine(
                  "Inner exception was: {0}", e.InnerException.Message);
         }
         catch(Exception e)
         {
            Console.WriteLine("Exception occurred:\n" + e.Message);
         }         
         finally
         {
            peopleToRing.Dispose();
         }
         Console.ReadLine();
      }
   }

   class ColdCallFileReader :IDisposable
   {
      FileStream fs;
      StreamReader sr;
      uint nPeopleToRing;
      bool isDisposed = false;
      bool isOpen = false;

      public void Open(string fileName)
      {
         if (isDisposed)
            throw new ObjectDisposedException("peopleToRing");
         fs = new FileStream(fileName, FileMode.Open);
         sr = new StreamReader(fs);
         try 
         {
            string firstLine = sr.ReadLine();
            nPeopleToRing = uint.Parse(firstLine);
            isOpen = true;
         }
         catch (FormatException e)
         {
            throw new ColdCallFileFormatException(
               "First line isn\'t an integer", e);
         }
      }

      public uint NPeopleToRing
      {
         get
         {
            if (isDisposed)
               throw new ObjectDisposedException("peopleToRing");
            if (!isOpen)
               throw new UnexpectedException(
                  "Attempt to access cold call file that is not open");
            return nPeopleToRing;
         }
      }

      public void Dispose()
      {
         if (isDisposed)
            return;

         isDisposed = true;
         isOpen = false;
         if (fs != null)
         {
            fs.Close();
            fs = null;
         }
      }

      public void ProcessNextPerson()
      {
         if (isDisposed)
            throw new ObjectDisposedException("peopleToRing");
         if (!isOpen)
            throw new UnexpectedException(
               "Attempt to access cold call file that is not open");
         try
         {
            string name;
            name = sr.ReadLine();
            if (name == null)
               throw new ColdCallFileFormatException("Not enough names");
            if (name[0] == 'B')
            {
                throw new SalesSpyFoundException(name);
            }
            Console.WriteLine(name);
         }
         catch(SalesSpyFoundException e)
         {
            Console.WriteLine(e.Message);
         }

         finally
         {
         }
      }
   }

    class SalesSpyFoundException : ApplicationException
   {
      public SalesSpyFoundException(string spyName)
         :   base("LandLine spy found, with name " + spyName)
      {
      }

      public SalesSpyFoundException(string spyName, Exception innerException)
         :   base("LandLine spy found, with name " + spyName, innerException)
      {
      }
   }

   class ColdCallFileFormatException : ApplicationException
   {
      public ColdCallFileFormatException(string message)
         :   base(message)
      {
      }

      public ColdCallFileFormatException(string message, Exception innerException)
         :   base(message, innerException)
      {
      }
   }

   class UnexpectedException : ApplicationException
   {
      public UnexpectedException(string message)
         :   base(message)
      {
      }

      public UnexpectedException(string message, Exception innerException)
         :   base(message, innerException)
      {
      }
   }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值