C#【中级篇】C# 异常处理
前言
异常是在程序执行期间出现的问题。C# 中的异常是对程序运行时出现的特殊情况的一种响应,比如尝试除以零。
异常提供了一种把程序控制权从某个部分转移到另一个部分的方式。C# 异常处理时建立在四个关键词之上的:try、catch、finally 和 throw。
- try:一个 try 块标识了一个将被激活的特定的异常的代码块。后跟一个或多个 catch 块。
- catch:程序通过异常处理程序捕获异常。catch 关键字表示异常的捕获。
- finally:finally 块用于执行给定的语句,不管异常是否被抛出都会执行。例如,如果您打开一个文件,不管是否出现异常文件都要被关闭。
- throw:当问题出现时,程序抛出一个异常。使用 throw 关键字来完成。
一、语法
假设一个块将出现异常,一个方法使用 try 和 catch 关键字捕获异常。try/catch 块内的代码为受保护的代码,使用 try/catch 语法如下所示:
try
{
// 引起异常的语句
}
catch( ExceptionName e1 )
{
// 错误处理代码
}
catch( ExceptionName e2 )
{
// 错误处理代码
}
catch( ExceptionName eN )
{
// 错误处理代码
}
finally
{
// 要执行的语句
}
您可以列出多个 catch 语句捕获不同类型的异常,以防 try 块在不同的情况下生成多个异常。
二、C# 中的异常类
C# 异常是使用类来表示的。C# 中的异常类主要是直接或间接地派生于 System.Exception 类。System.ApplicationException 和 System.SystemException 类是派生于 System.Exception 类的异常类。
System.ApplicationException 类支持由应用程序生成的异常。所以程序员定义的异常都应派生自该类。
System.SystemException 类是所有预定义的系统异常的基类。
下表列出了一些派生自 System.SystemException 类的预定义的异常类:
异常类 | 描述 |
---|---|
System.IO.IOException | 处理 I/O 错误。 |
System.IndexOutOfRangeException | 处理当方法指向超出范围的数组索引时生成的错误。 |
System.ArrayTypeMismatchException | 处理当数组类型不匹配时生成的错误。 |
System.NullReferenceException | 处理当依从一个空对象时生成的错误。 |
System.DivideByZeroException | 处理当除以零时生成的错误。 |
System.InvalidCastException | 处理在类型转换期间生成的错误。 |
System.OutOfMemoryException | 处理空闲内存不足生成的错误。 |
System.StackOverflowException | 处理栈溢出生成的错误。 |
三、异常处理
C# 以 try 和 catch 块的形式提供了一种结构化的异常处理方案。使用这些块,把核心程序语句与错误处理语句分离开。
这些错误处理块是使用 try、catch 和 finally 关键字实现的。下面是一个当除以零时抛出异常的实例:
using System;
namespace ErrorHandlingApplication
{
class DivNumbers
{
int result;
DivNumbers()
{
result = 0;
}
public void division(int num1, int num2)
{
try
{
result = num1 / num2;
}
catch (DivideByZeroException e)
{
Console.WriteLine("Exception caught: {0}", e);
}
finally
{
Console.WriteLine("Result: {0}", result);
}
}
static void Main(string[] args)
{
DivNumbers d = new DivNumbers();
d.division(25, 0);
Console.ReadKey();
}
}
}
运行结果:
英文
Exception caught: System.DivideByZeroException: Attempted to divide by zero.
at ...
Result: 0
中文
Exception caught: System.DivideByZeroException: 尝试除以零。
在 ErrorHandlingApplication.DivNumbers.division(Int32 num1, Int32 num2) 位置 E:\Desktop\C#\ConsoleApp1\Program.cs:行 号 15
Result: 0
四、创建用户自定义异常
您也可以定义自己的异常。用户自定义的异常类是派生自 ApplicationException 类。下面的实例演示了这点:
using System;
namespace UserDefinedException
{
class TestTemperature
{
static void Main(string[] args)
{
Temperature temp = new Temperature();
try
{
temp.showTemp();
}
catch(TempIsZeroException e)
{
Console.WriteLine("TempIsZeroException: {0}", e.Message);
}
Console.ReadKey();
}
}
}
public class TempIsZeroException: ApplicationException
{
public TempIsZeroException(string message): base(message)
{
}
}
public class Temperature
{
int temperature = 0;
public void showTemp()
{
if(temperature == 0)
{
throw (new TempIsZeroException("Zero Temperature found"));
}
else
{
Console.WriteLine("Temperature: {0}", temperature);
}
}
}
运行结果:
TempIsZeroException: Zero Temperature found
五、抛出对象【需要补充实例】
如果异常是直接或间接派生自 System.Exception 类,您可以抛出一个对象。您可以在 catch 块中使用 throw 语句来抛出当前的对象,如下所示:
catch(Exception e)
{
...
throw e;
}
实例1【显式地抛出异常】:
可以使用throw语句使代码显式地引发一个异常。代码如下:
using System;
class MyClass
{
public static void PrintArg(string arg)
{
try
{
if (arg == null)
{
ArgumentNullException myEx = new ArgumentNullException("arg");//【1】此种情况下,结果输出参数arg的值为null。(“arg”)提供null参数的名称
//ArgumentNullException myEx = new ArgumentNullException();//【2】此种情况下,结果不会指明哪个参数值为null,请自己测试!
throw myEx;
}
Console.WriteLine(arg);
}
catch (ArgumentNullException e)
{
Console.WriteLine("Message: {0}", e.Message);
}
}
}
class Program
{
static void Main()
{
string s = null;
MyClass.PrintArg(s);
MyClass.PrintArg("Hi there!");
Console.ReadLine();
}
}
运行结果:
Message: 值不能为 null。
参数名: arg
Hi there!
实例2【不带异常对象的抛出】:
throw语句还可以不带异常对象使用,在catch块内部:
- 这种形式重新抛出当前异常,系统继续它的搜索,为该异常寻找另外的处理代码。
- 这种形式只能在catch语句内部。
using System;
class MyClass
{
public static void PrintArg(string arg)
{
try
{
try
{
if (arg == null)
{
ArgumentNullException myEx = new ArgumentNullException("arg");
throw myEx;
}
Console.WriteLine(arg);
}
catch (ArgumentNullException e)
{
Console.WriteLine("Inner Catch: {0}", e.Message);
throw;
}
}
catch
{
Console.WriteLine("Outer Catch: Handling an Exception.");
}
}
}
class Program
{
static void Main()
{
string s = null;
MyClass.PrintArg(s);
Console.ReadLine();
}
}
运行结果:
Inner Catch: 值不能为 null。
参数名: arg
Outer Catch: Handling an Exception.
总结
- 理解try、catch、finally、throw的作用并会实际使用。
相关文章
- C#Light for Unity 新例子
- C#由转换二进制所引起的思考,了解下?
- Why exceptions in async methods are “dangerous” in C# 调用async方法,不进行await的时候,会丢失异常 exception disappear in async method
- C#中的异常处理
- c# 中内部类的简单介绍 C#内部类
- 如何使用T-SQL备份还原数据库及c#如何调用执行? C#中索引器的作用和实现。 jquery控制元素的隐藏和显示的几种方法。 localStorage、sessionStorage用法总结 在AspNetCore中扩展Log系列 - 介绍开源类库的使用(一) span<T>之高性能字符串操作实测
- C#不用union,而是有更好的方式实现 .net自定义错误页面实现 .net自定义错误页面实现升级篇 .net捕捉全局未处理异常的3种方式 一款很不错的FLASH时种插件 关于c#中委托使用小结 WEB网站常见受攻击方式及解决办法 判断URL是否存在 提升高并发量服务器性能解决思路
- C# 插件热插拔 .NET:何时应该 “包装异常”? log4.net 自定义日志文件名称
- 《C#多线程编程实战(原书第2版)》——1.12 处理异常
- MFC和c#中模拟对另一进程的窗口按钮点击
- [C#] Direct2D 学习笔记 (一)vb.net转换为c#
- C# 中的异常处理
- C# 中的异常捕获和处理
- C# new关键字和对象类型转换(双括号、is操作符、as操作符)
- C# 使用反射获取私有属性的方法
- C#多线程中的异常处理
- 【C#/WPF】键盘事件
- C# CefSharp MemoryStreamResponseFilter这个类使用过程中遇到的bug,dataIn.CopyTo(dataOut)异常