我今天做了一些.NET编码,我遇到了一些我以前从未想过的东西--微软用于测试网络连通性的许多内置方法(ping、TCP socket等)。在连接失败时抛出异常是非常自由的。
当然,在一般情况下,在程序的控制流中使用异常是不好的。但是我很好奇--如果.NET库如此容易地抛出它们,我如何才能避免这样的事情(原谅可能是混乱的代码,只是抛出一个示例):
bool TestConnection(string host)
{
bool connected;
Ping ping = new Ping();
PingReply reply = ping.Send(host);
connected = (reply.Status == IPStatus.Success);
return connected; // possibly won't return false because of exceptions
}我可以使用try-catch块来处理异常,但我要做的就是将connected设置为false。既然我丢弃了异常中的所有信息,那不是基本上完全吞噬了异常吗?这里的最佳实践是什么?
发布于 2011-02-16 02:03:16
您肯定应该捕获.NET框架抛出的异常,并且不要假设您唯一能做的事情就是返回false,这取决于您的应用程序设计和用例。例如,您可以重新抛出异常并通知上层输入的网络路径不再存在,或者您返回false而在其他情况下忽略该问题。
.NET框架是我们用来构建东西的基础,它必须是通用的,如果你试图打开一个不存在的文件,它会抛出FileNotFoundException,在某些情况下,你会创建它,在其他一些情况下,你会告诉用户你找不到文件……它总是依赖于你自己的代码,基本的异常要么用防御性的方法避免,要么被捕获。:)
发布于 2011-02-16 02:10:14
如果可能的话,你应该为控制流使用异常来避免。例如,使用TryParse而不是解析,检查正确的类型或非空,而不是捕获空引用或类型转换异常。
但是在这种情况下,您没有另一个可用的接口,所以您必须使用可用的接口。请注意,如果不能捕获TestConnection中的异常,则意味着函数的调用者必须执行此操作,这将是更大的邪恶。
发布于 2011-02-16 02:10:46
这取决于方法的目的。例如,如果您只想获取一个布尔值来确定是否可以建立连接,则捕获异常并返回false。
bool CanConnect(string host)
{
bool connected;
Ping ping = new Ping();
try
{
PingReply reply = ping.Send(host);
}
catch(/*catch the specific exception(s) here*/)
{
return false;
}
connected = (reply.Status == IPStatus.Success);
return connected; // possibly won't return false because of exceptions
}但是,如果您希望测试连接并提供有关连接失败原因的更具体的错误,则不希望在此方法中捕获异常。您可能希望通过允许异常冒泡来让调用者确切地知道哪里出了问题。
这与微软的异常处理指南是一致的:
不要过度使用catch。通常应该允许异常在调用堆栈中向上传播。捕获无法合法处理的异常会隐藏关键的调试信息。
(来自MS Exception Handling Guidelines)
这不是使用异常来操作控制流。This answer给出了一个为控制流使用异常的示例。
https://stackoverflow.com/questions/5007484
复制相似问题