C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C# throw new Exception()

C#之throw new Exception()的实现示例

作者:*Major*-莙工科技有限公司

本文主要介绍了C#之throw new Exception()的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在 C# 开发中,异常处理是构建健壮应用程序的核心机制。throw new Exception(result); 作为基础异常抛出方式,其使用场景与潜在陷阱值得深入探讨。本文将结合微软官方文档与实际案例,从底层原理到最佳实践全面解析这一关键语法。

一、基础语法解析

1. 异常对象构造

throw new Exception(result); 创建了一个继承自 System.Exception 的新异常对象,其核心参数 result 作为错误信息存储在 Message 属性中。例如:

try 
{
    int divisor = 0;
    if (divisor == 0) 
    {
        throw new Exception("Division by zero is not allowed");
    }
    int result = 10 / divisor;
} 
catch (Exception ex) 
{
    Console.WriteLine($"Error: {ex.Message}"); // 输出: Error: Division by zero is not allowed
}

2. 异常类型选择

微软官方明确建议避免直接抛出 System.Exception 基类,而应使用更具体的派生类:

示例改进:

if (divisor == 0) 
{
    throw new InvalidOperationException("Divisor cannot be zero");
}

二、异常处理链的完整流程

1. 异常传播机制

当异常被抛出时,CLR 会沿调用栈向上查找匹配的 catch 块。关键区别在于 throwthrow ex 的差异:

try 
{
    ProcessData();
} 
catch (Exception ex) 
{
    LogError(ex);
    throw; // 保留完整堆栈
    // throw ex; // 错误:会破坏调试信息
}

2. 异常筛选器(C# 6.0+)

通过 when 关键字实现条件化异常处理:

try 
{
    int.Parse("abc");
} 
catch (FormatException ex) when (ex.Message.Contains("input string")) 
{
    Console.WriteLine("Specific format error handled");
}

三、高级应用场景

1. 异常数据增强

通过 Exception.Data 字典附加上下文信息:

try 
{
    ValidateUser();
} 
catch (UnauthorizedAccessException ex) 
{
    ex.Data.Add("UserId", CurrentUserId);
    ex.Data.Add("Timestamp", DateTime.Now);
    throw;
}

2. 异步异常处理

async/await 模式中,异常会封装在 AggregateException 中:

async Task ProcessAsync() 
{
    try 
    {
        await SomeAsyncOperation();
    } 
    catch (AggregateException ae) 
    {
        foreach (var innerEx in ae.InnerExceptions) 
        {
            Console.WriteLine(innerEx.Message);
        }
    }
}

3. 自定义异常类

创建包含业务特定属性的异常类型:

public class PaymentProcessingException : Exception 
{
    public decimal Amount { get; }
    public string TransactionId { get; }

    public PaymentProcessingException(decimal amount, string transactionId, string message) 
        : base(message) 
    {
        Amount = amount;
        TransactionId = transactionId;
    }
}

// 使用示例
throw new PaymentProcessingException(100m, "TX123", "Insufficient funds");

四、性能优化与最佳实践

1. 异常处理成本

建议

2. 日志集成最佳实践

try 
{
    // 业务逻辑
} 
catch (Exception ex) 
{
    logger.LogError(ex, "Failed to process order {OrderId}", orderId);
    throw; // 重新抛出前记录完整上下文
}

3. 全球异常处理

在 ASP.NET Core 中通过中间件统一处理未捕获异常:

app.UseExceptionHandler(errorApp => 
{
    errorApp.Run(async context => 
    {
        context.Response.StatusCode = 500;
        var ex = context.Features.Get<IExceptionHandlerFeature>()?.Error;
        await context.Response.WriteAsync($"Error: {ex?.Message}");
    });
});

五、常见误区与解决方案

1. 过度使用异常

错误示例

// 错误:用异常控制正常流程
try 
{
    int.TryParse("123", out int result);
} 
catch (FormatException) 
{
    result = 0; // 不推荐
}

正确做法

if (!int.TryParse("123", out int result)) 
{
    result = 0;
}

2. 暴露敏感信息

错误示例

throw new Exception($"Database connection failed: {connectionString}");

安全实践

throw new Exception("Database connection failed. See logs for details.");
// 同时在日志中记录完整信息(确保日志安全)
logger.LogError("Database connection failed for user {UserId}", userId);

六、进阶技巧

1. 异常链构建

通过 InnerException 保留原始异常上下文:

try 
{
    // 外层操作
} 
catch (OuterException outerEx) 
{
    try 
    {
        // 补救操作
    } 
    catch (InnerException innerEx) 
    {
        throw new AggregateException("Outer operation failed", outerEx, innerEx);
    }
}

2. 资源清理模式

结合 usingtry/finally 确保资源释放:

FileStream fs = null;
try 
{
    fs = new FileStream("file.txt", FileMode.Open);
    // 处理文件
} 
finally 
{
    fs?.Dispose();
}

// 更简洁的C# 8.0+写法
using var fs = new FileStream("file.txt", FileMode.Open);

七、总结

throw new Exception(result); 作为异常处理的起点,其正确使用需要遵循以下原则:

  1. 选择最具体的异常类型
  2. 提供有意义的错误信息
  3. 保持异常链完整性
  4. 避免异常用于流程控制
  5. 记录完整的调试上下文

到此这篇关于C#之throw new Exception()的实现示例的文章就介绍到这了,更多相关C# throw new Exception()内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文