一、捕获异常
在 C#中,可以通过"try-catch"块捕获异常,并通过"is"关键字或"as"关键字来判断异常的具体类型。以下是几种常见的方法来判断异常类型:
方法 1:使用"catch"块直接捕获特定类型的异常
在 C#中,可以在"catch"块中直接指定要捕获的异常类型。这种方式可以在捕获异常时直接区分不同类型的异常。
cs
try
{
// 可能抛出异常的代码
int result = 10 / 0;
}
catch (DivideByZeroException ex) // 捕获特定类型的异常
{
Console.WriteLine("捕获到除零异常: " + ex.Message);
}
catch (Exception ex) // 捕获所有其他类型的异常
{
Console.WriteLine("捕获到其他异常: " + ex.Message);
}
方法 2:使用"is"关键字判断异常类型
如果捕获到的异常是"Exception"类型,可以在"catch"块中使用"is"关键字来判断异常的具体类型。
cs
try
{
// 可能抛出异常的代码
throw new ArgumentException("这是一个参数异常");
}
catch (Exception ex)
{
if (ex is ArgumentException)
{
Console.WriteLine("捕获到 ArgumentException: " + ex.Message);
}
else if (ex is InvalidOperationException)
{
Console.WriteLine("捕获到 InvalidOperationException: " + ex.Message);
}
else
{
Console.WriteLine("捕获到其他类型的异常: " + ex.Message);
}
}
方法 3:使用"as"关键字判断异常类型"as"关键字
可以将异常对象转换为特定的类型,如果转换成功,则说明异常是该类型或其派生类型。
cs
try
{
// 可能抛出异常的代码
throw new FileNotFoundException("文件未找到");
}
catch (Exception ex)
{
FileNotFoundException fileEx = ex as FileNotFoundException;
if (fileEx != null)
{
Console.WriteLine("捕获到 FileNotFoundException: " + fileEx.Message);
}
else
{
Console.WriteLine("捕获到其他类型的异常: " + ex.Message);
}
}
方法 4:使用"GetType()"方法获取异常类型
可以通过"GetType()"方法获取异常的类型信息。
cs
try
{
// 可能抛出异常的代码
throw new NullReferenceException("引用为空");
}
catch (Exception ex)
{
Console.WriteLine("捕获到的异常类型是: " + ex.GetType().Name);
Console.WriteLine("异常信息: " + ex.Message);
}
方法 5:使用"when"关键字(C# 6.0+)
C# 6.0 引入了"when"关键字,可以在"catch"块中添加条件,从而更灵活地捕获特定类型的异常。
cs
try
{
// 可能抛出异常的代码
throw new Exception("这是一个普通异常");
}
catch (Exception ex) when (ex is ArgumentException)
{
Console.WriteLine("捕获到 ArgumentException: " + ex.Message);
}
catch (Exception ex) when (ex is InvalidOperationException)
{
Console.WriteLine("捕获到 InvalidOperationException: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("捕获到其他类型的异常: " + ex.Message);
}
总结
• 如果你希望直接捕获特定类型的异常,推荐使用方法 1(直接在 catch 块中指定异常类型)。
• 如果你需要在捕获到异常后进一步判断类型,可以使用 "is"、"as" 或 "GetType()" 方法。
• 如果你使用的是 C# 6.0 或更高版本,"when 关键字可以提供更灵活的异常捕获逻辑。
根据你的具体需求选择合适的方法即可!
二、抛出异常
在C#中,抛出异常是一种处理程序运行时错误或异常情况的机制。你可以使用 throw 关键字来抛出自定义异常或预定义的异常类型。以下是抛出异常的几种常见方式:
1、抛出预定义的异常
C# 提供了许多预定义的异常类型,如 ArgumentException 、 ArgumentNullException 、 InvalidOperationException 等。你可以直接使用这些异常类型来抛出异常。
cs
public void Divide(int a, int b)
{
if (b == 0)
{
throw new DivideByZeroException("除数不能为零!");
}
Console.WriteLine(a / b);
}
在这个例子中,如果 b 为0,程序会抛出一个 DivideByZeroException ,并附带一条错误信息。
2. 抛出自定义异常
你可以创建自己的异常类,继承自 Exception 或其子类。自定义异常类可以包含额外的属性和方法,以提供更多上下文信息。
cs
public class MyCustomException : Exception
{
public MyCustomException(string message) : base(message)
{
}
public MyCustomException(string message, Exception innerException) : base(message, innerException)
{
}
}
public void CheckAge(int age)
{
if (age < 18)
{
throw new MyCustomException("年龄必须大于或等于18岁!");
}
Console.WriteLine("年龄验证通过!");
}
在这个例子中, MyCustomException 是一个自定义异常类, CheckAge 方法会在年龄小于18时抛出这个自定义异常。
3、重新抛出异常
在捕获异常后,你可能需要对异常进行处理,然后重新抛出它,或者抛出一个新的异常。这可以通过 throw 关键字实现。
cs
try
{
// 模拟一个异常
throw new InvalidOperationException("原始异常");
}
catch (Exception ex)
{
Console.WriteLine("捕获到异常:" + ex.Message);
// 重新抛出原始异常
throw;
// 或者抛出一个新的异常
// throw new ApplicationException("新的异常", ex);
}
在这个例子中:
使用 throw;重新抛出捕获到的原始异常。
使用 throw new Exception(...); 可以抛出一个新的异常,并将原始异常作为内部异常传递。
4、抛出异常时附带堆栈信息
当你抛出一个新的异常时,可以通过 innerException 参数将原始异常的堆栈信息保留下来。这有助于调试和错误追踪。
cs
try
{
throw new InvalidOperationException("原始异常");
}
catch (Exception ex)
{
throw new ApplicationException("新的异常", ex);
}
在这个例子中, ApplicationException 的构造函数中传递了原始异常 ex 作为 innerException ,这样可以保留完整的堆栈跟踪信息。
5、使用 ArgumentNullException 和 ArgumentException
在方法中检查参数时,如果参数不符合要求,通常会抛出 ArgumentNullException 或 ArgumentException 。
cs
public void PrintName(string name)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name), "参数不能为空!");
}
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("参数不能为空或空白!", nameof(name));
}
Console.WriteLine(name);
}
总结
在C#中,抛出异常是一种重要的错误处理机制。你可以:
1、抛出预定义的异常(如 ArgumentException 、 InvalidOperationException 等)。
2、创建并抛出自定义异常。
3、在捕获异常后重新抛出或抛出新的异常。
4、通过 innerException 保留原始异常的堆栈信息。
合理使用异常机制可以提高代码的健壮性和可维护性。
三、常见的异常类
在C#中,.NET框架提供了许多预定义的异常类,用于处理各种运行时错误和异常情况。这些异常类都继承自 System.Exception 类。以下是一些常用的异常类及其用途:
1、系统级异常
这些异常通常由运行时环境抛出,表示程序运行时发生了严重错误。
System.Exception:所有异常的基类。通常不直接抛出,而是作为其他异常的基类。
System.SystemException:表示由.NET运行时环境抛出的系统级异常。
cs
throw new Exception("未知错误");
throw new SystemException("系统级错误");
2、程序逻辑异常
这些异常通常由程序逻辑错误引起,例如无效的参数、非法操作等。
System.ArgumentException :表示传递给方法的参数无效。
System.ArgumentNullException:表示传递给方法的参数为 null 。
System.ArgumentOutOfRangeException:表示参数的值超出了预期范围。
cs
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException("参数不能为空!", nameof(name));
}
if (name == null)
{
throw new ArgumentNullException(nameof(name), "参数不能为空!");
}
if (age < 0)
{
throw new ArgumentOutOfRangeException(nameof(age), "年龄不能为负数!");
}
3、运行时异常
这些异常通常由运行时环境抛出,表示程序运行时发生了错误。
System.InvalidOperationException:表示在当前状态下无法执行操作。
System.NotSupportedException:表示尝试执行不支持的操作。
System.NotImplementedException:表示方法或操作尚未实现。
cs
if (list.Count == 0)
{
throw new InvalidOperationException("列表为空,无法执行操作!");
}
throw new NotSupportedException("此操作不支持!");
throw new NotImplementedException("此方法尚未实现!");
4、IO和资源异常
这些异常通常与文件、网络或其他资源操作有关。
System.IO.IOException:表示I/O操作失败。
System.IO.FileNotFoundException:示指定的文件未找到。
System.IO.DirectoryNotFoundException:表示指定的目录未找到。
cs
throw new IOException("I/O操作失败!");
throw new FileNotFoundException("文件未找到!", "example.txt");
throw new DirectoryNotFoundException("目录未找到!");
5、线程和并发异常
这些异常通常与多线程或并发操作有关。
System.Threading.ThreadAbortException:表示线程被中止。
System.Threading.SynchronizationLockException:示在尝试进入同步块时发生错误。
cs
throw new ThreadAbortException("线程被中止!");
throw new SynchronizationLockException("同步锁异常!");
6、 数据和格式异常
这些异常通常与数据格式或类型转换有关。
System.FormatException:表示字符串格式不正确。
System.InvalidCastException:表示尝试将对象强制转换为不兼容的类型。
System.OverflowException:表示算术运算超出数据类型的范围。
cs
throw new FormatException("格式不正确!");
throw new InvalidCastException("类型转换失败!");
throw new OverflowException("数值溢出!");
7、网络和通信异常
这些异常通常与网络操作或通信失败有关。
System.Net.Sockets.SocketException:表示套接字操作失败。
System.Net.WebException:表示Web请求失败。
cs
throw new SocketException("套接字操作失败!");
throw new WebException("Web请求失败!");
8、其他常见异常
System.DivideByZeroException:表示除数为零。
System.NullReferenceException:表示尝试访问 null 对象的成员。
System.ApplicationException: 表示应用程序级错误(较少使用)。
cs
throw new DivideByZeroException("除数不能为零!");
throw new NullReferenceException("对象引用未设置为对象的实例!");
throw new ApplicationException("应用程序错误!");
总结
这些异常类覆盖了大多数常见的错误场景。在实际开发中,选择合适的异常类可以更清晰地表达错误的性质,便于调试和维护。同时,合理使用异常机制可以提高程序的健壮性和用户体验。