11. C#高级进阶
一、C# 异常处理
在 C# 中,异常是在程序运行出错时引发的,所有异常都派生自 System.Exception 类。异常处理就是处理运行时错误的过程,通过异常处理可以使程序在发生错误时保持正常运行。
C# 中的异常处理基于四个关键字构建,分别是:try、catch、finally 和 throw。
- try:try 语句块中通常用来存放容易出现异常的代码,其后面紧跟一个或多个 catch 语句块;
- catch:catch 语句块用来捕获 try 语句块中出现的异常;
- finally:finally 语句块用于执行特定的语句,不管异常是否被抛出都会执行;
- throw:throw 用来抛出一个异常;
1、try/catch语句
假设一段代码会引发异常,则可以使用 try 和 catch 组合来捕获这个异常。举例如下:
try
{
int a = 123;
int b = 0;
int x = a / b;
}
catch (Exception e)
{
Console.WriteLine("捕获到的异常:{0}", e);
}
finally
{
Console.WriteLine("finally 语句块中的代码!");
}
Console.ReadKey();
2、C# 中的异常类
C# 中的异常类主要是从 System.Exception 类派生的。比如 System.ApplicationException 和 System.SystemException 就是从 System.Exception 类派生的。
- System.ApplicationException 类支持由程序产生的异常,因此我们自定义的异常类都应继承此类;
- System.SystemException 类是所有系统预定义异常的基类;
下表中列举了一些从 Sytem.SystemException 类派生的预定义异常类:
异常类 | 描述 |
---|---|
System.IO.IOException | 处理 I/O 错误 |
System.IndexOutOfRangeException | 处理当方法引用超出数组范围的索引时产生的错误 |
System.ArrayTypeMismatchException | 处理当数组类型不匹配时产生的错误 |
System.NullReferenceException | 处理引用一个空对象时产生的错误 |
System.DivideByZeroException | 处理当除以零时产生的错误 |
System.InvalidCastException | 处理在类型转换期间产生的错误 |
System.OutOfMemoryException | 处理空闲内存不足产生的错误 |
System.StackOverflowException | 处理栈溢出产生的错误 |
3、自定义异常类
除了可以使用系统预定义的异常类外,我们还可以自行定义异常类,自定义的异常类都应继承 System.ApplicationException 类。
class Program
{
static void Main(string[] args)
{
TestUserDefinedException test = new TestUserDefinedException();
try
{
test.Validate(12);
} catch (InvalidAgeException e)
{
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
}
public class InvalidAgeException : ApplicationException
{
public InvalidAgeException(string message) : base(message)
{
}
}
public class TestUserDefinedException
{
public void Validate(int age)
{
if (18 > age)
{
throw new InvalidAgeException("Sorry, Age must be greater than 18");
}
}
}
4、C# 抛出异常
如果异常是直接或间接派生自 System.Exception 类,则可以在 catch 语句块中使用 throw 语句抛出该异常。throw 语句的语法格式如下所示:
catch (Exception e)
{
......
throw e
}
二、C# 目录操作
C# 中允许您使用各种目录和文件相关的类来操作目录和文件,比如 DirectoryInfo 类和 FileInfo 类。
1、DirectoryInfo 类
DirectoryInfo 类派生自 FileSystemInfo 类。其中提供了各种用于创建、移动、浏览目录和子目录的方法。需要注意的是,该类不能被继承。
下表列出了 DirectoryInfo 类中一些常用的属性和方法:
属性/方法 | 描述 |
---|---|
Attributes | 获取当前文件或目录的属性 |
CreationTime | 获取当前文件或目录的创建时间 |
Exists | 获取一个表示目录是否存在的布尔值 |
Extension | 获取表示文件扩展名部分的字符串 |
FullName | 获取目录或文件的完整路径 |
LastAccessTime | 获取当前文件或目录最后被访问的时间 |
Name | 获取此 DirectoryInfo 实例的名称 |
public void Create() | 创建一个目录 |
public DirectoryInfo CreateSubdirectory(string path) | 在指定的路径上创建子目录,指定的路径可以是相对于 DirectoryInfo 类的实例的路径 |
public override void Delete() | 如果为空的,则删除该 DirectoryInfo |
public DirectoryInfo[] GetDirectories() | 返回当前目录的子目录 |
public FileInfo[] GetFiles() | 从当前目录返回文件列表 |
2、FileInfo 类
FileInfo 类派生自 FileSystemInfo 类,其中提供了用于创建、复制、删除、移动、打开文件的属性和方法。与 DirectoryInfo 类相同,FileInfo 类也不能被继承。
下表列出了 FileInfo 类中一些常用的属性和方法:
属性 | 描述 |
---|---|
Attributes | 获取当前文件的属性 |
CreationTime | 获取当前文件的创建时间 |
Directory | 获取文件所属目录的一个实例 |
Exists | 获取一个表示文件是否存在的布尔值 |
Extension | 获取表示文件存在的字符串 |
FullName | 获取文件的完整路径 |
LastAccessTime | 获取当前文件最后被访问的时间 |
LastWriteTime | 获取文件最后被写入的时间 |
Length | 获取当前文件的大小,以字节为单位 |
Name | 获取文件的名称 |
public StreamWriter AppendText() | 创建一个 StreamWriter,追加文本到由 FileInfo 的实例表示的文件中 |
public FileStream Create() | 创建一个文件 |
public override void Delete() | 永久删除一个文件 |
public void MoveTo(string destFileName) | 移动一个指定的文件到一个新的位置,提供选项来指定新的文件名 |
public FileStream Open(FileMode mode) | 以指定的模式打开一个文件 |
public FileStream Open(FileMode mode,FileAccess access) | 以指定的模式,使用 read、write 或 read/write 访问,来打开一个文件 |
public FileStream Open(FileMode mode,FileAccess access,FileShare share) | 以指定的模式,使用 read、write 或 read/write 访问,以及指定的分享选项,来打开一个文件 |
public FileStream OpenRead() | 创建一个只读的 FileStream |
public FileStream OpenWrite() | 创建一个只写的 FileStream |
举例:
// 创建一个 DirectoryInfo 对象
DirectoryInfo dir = new DirectoryInfo(@"C:\Users\Administrator\Desktop\cs");
Console.WriteLine("获取当前目录的属性: {0}", dir.Attributes);
Console.WriteLine("获取当前目录的创建时间: {0}", dir.CreationTime);
Console.WriteLine("获取当前目录是否存在: {0}", dir.Exists);
Console.WriteLine("获取当前文件扩展名部分的字符串: {0}", dir.Extension);
Console.WriteLine("获取当前目录的完整路径: {0}", dir.FullName);
Console.WriteLine("获取上次访问当前目录的时间: {0}", dir.LastAccessTime);
Console.WriteLine("获取 DirectoryIndiro 实例的名称: {0}", dir.Name);
// 获取目录中的文件以及它们的名称和大小
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
Console.WriteLine("文件名称:{0} ,大小:{1}", file.Name, file.Length);
}