扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
异常还没出现前,处理错误最经典的方式就是使用错误代码检查语句了。例如
public sealed class Painful
{
...
private static char[] ReadSource(string filename)
{
FileInfo file = new FileInfo(filename);
if (errorCode == 2342) goto handler;
int length = (int)file.Length;
char[] source = new char[length];
if (errorCode == -734) goto handler;
TextReader reader = file.OpenText();
if (errorCode == 2664) goto handler;
reader.Read(source, 0, length);
if (errorCode == -5227) goto handler;
reader.Close();
Process(filename, source);
return source;
handler:
...
}
}
这种编码方式单调乏味,翻来复去,难以使用,看起来非常的复杂,而且还使得基本功能很不清晰。并且还很容易忽略错误(故意或者偶尔的遗忘)。现在好了,有很多来处理这种情况,但是其中必有一些处理方式要好过其他的。
二、关系分离
异常所能做到的最基本的事情就是允许你将错误和基本功能分离开来。换句话,我们能将上面的改写如下:
...
public sealed class PainLess
{
public static int Main(string[] args)
{
try
{
string filename = args[0];
char[] source = ReadSource(filename);
Process(filename, source);
return 0;
}
catch (SecurityException caught) { ... }
catch (IOException caught) { ... }
catch (OutOfMemoryException caught) { ... }
...
}
private static char[] ReadSource(string filename)
{
FileInfo file = new FileInfo(filename);
int length = (int)file.Length;
char[] source = new char[length];
TextReader reader = file.OpenText();
reader.Read(source, 0, length);
reader.Close();
return source;
}
}
在转化过程中,需要注意以下几点:
1.以前使用数字作为错误代码来描述错误(很失败的一种做法,谁知道2342是什么意思呢?),现在使用命名的异常类来描述(例如:SecurityException)。
2.异常类彼此之间的关系并没有紧密的联系在一起。相反的,用来描述某一类错误的整数代码在整个错误描述代码中必须是唯一。
3. 在ReadSource方法中没有没有抛出详细说明。在C#中抛出说明并不是必须的。
然而,最值得注意是:比较两段代码,ReadSource变得非常的清晰、简单、明了。它现在仅包含需要实现其基本功能的语句,没有表现出明显的错误处理。这是可以的,因为如果出现异常,调用堆栈就会自我展开。这个版本是我们想要的“理想”版本。
然而,异常允许我们接近这个ReadSource的理想版本,同时,又阻止我们到达它。ReadSource是一个编码例子,它请求资源(一个TextReader),使用了资源(Read),并且释放了资源(Close)。
问题是如果在请求资源的过程中出现了异常,那么资源将不会被释放。这个问题的解决是本文的一部分。不过,“理想“中的ReadSource版本仍然是有用的。我们将使用它做为下面几个版本的ReadSource评价的参照物。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者