C#(面向对象的托管语言)类库(区别于应用程序)的异常处理思路

1、不要做出任何应用程序才需要考虑抉择策略,不能想当然的决定一些错误情形。具体的一个体现形式是什么异常都捕获。这不是类库的职责,因为无法掌握所有的调用者的使用情形,这些不确定性是委托、虚方法、接口等特性带来的。

一个直观的例子是调用者可能故意在委托中抛出异常以便在后面的逻辑中捕获它。

同时编写类库与应用程序的开发者往往会混淆二者的边界。

 

2、务必使用finally保证清理代码的执行。(或者相关语法糖using、lock等)

 

3、从异常状态中恢复。

类库方法也会调用其它类库方法,如果知道方法会抛出什么异常并且能够恢复的话,就去处理它。

 

4、如果修改状态,就要做好出错的准备,在发生无法恢复的异常时回滚部分完成的操作。

 

5、有时可以考虑隐藏实现细节来维系协定,专注于当前类库的业务。(慎用,调试变困难了)

比如一个转换工具类,捕获文件不存在的异常,抛出自定义的转换失败异常。

 

6、在方法无法完成其功能时选择抛出异常是最佳的对象模型。在调用者指出频繁抛出异常导致性能问题时才考虑提供Tryxxx方法。

Tryxxx方法不代表捕获所有异常,它返回false只代表那一种高频的错误,其它错误仍然抛出异常。

一个典型的例子就是官方库中的int.TryParse。返回false只代表字符串无法解析为int。当遇到内存不足或实参无效时,它仍然会抛出异常。

 

7、有必要强调,Tryxxx方法是为了规避频繁触发一种或一类异常而设计的。它并不是为了捕获所有异常而设计。

一个典型的例子就是官方库中的int.TryParse。返回false只代表字符串无法解析为int。当遇到内存不足或实参无效时,它仍然会抛出异常。

 

8、不要使用错误码(包括true/false表示的特殊错误码)代替异常处理。

因为clr与类库选择抛出异常,而你的方法采用错误码。现在所有人都需要处理两种机制。

 

所以在C#中设计一个方法,最后的总结是:完成动作或抛出异常;预见高频错误与简化错误处理时提供有限的状态码;有限的状态码预见有限的错误;布尔类型是最简洁的状态码,返回布尔类型不代表不会抛出异常。

 

posted @ 2024-03-23 17:56  陈百川  阅读(18)  评论(0)    收藏  举报