处理常见错误:If-Then-Throw块与Code Contracts和Assert类

Chr*_*dge 6 c# assert coding-style exception code-contracts

当我开始编写方法时,我通常首先使用If-Then-Throw块检查方法中的异常条件.

public void ReadFile(string filePath)
{
    if (string.IsNullOrEmpty(filePath)
    {
        throw new ArgumentException(...
Run Code Online (Sandbox Code Playgroud)

这种风格看起来非常清晰易懂,但它占用的空间比我认为的要多.我希望能够以一种聪明的方式处理错误和异常情况,使得阅读这些错误的人能够轻松地处理这些错误,同时保持代码本身的清洁.

我看了一下Code Contracts,在我看来,在方法执行之前和之后某些条件的要求.对于一个空字符串来说,这似乎有点过分,我不确定你是否可以在方法本身中有合同条款,例如,如果路径不是null但在该路径上不存在文件.

我正在考虑使用的解决方案是滚动我自己的Assert类.这个类基本上将上面的If-Then-Throw变成一个简单的一个衬里.

Assert.IsFalse<ArgumentException>(string.IsNullOrEmpty(filePath), "The path cannot be null or empty.");
Run Code Online (Sandbox Code Playgroud)

所有Assert方法都会使用异常类型和最后一个参数中的消息抛出异常.问题是我不确定这是不是很好的做法.它是否会混淆真正的异常,或Assert实际意味着什么?是否会使错误处理更容易或更难?

GEE*_*EEF 0

老实说,我不确定自定义 Assert 类是否有助于澄清任何事情,并且我不确定您是否应该担心两行需要检查并抛出异常而不是一行。您当前检查参数的方式也是我们做事的方式。事实上,我们代码中的大多数公共方法看起来都是这样的:

public void PerformStringOperation(string str1, string str2)
{
    if(string.IsNullOrEmpty(string1))
        throw new ArgumentNullException(...);
    if(string.IsNullOrEmpty(string2))
        throw new ArgumentNullException(...);

   // perform string operation(s) here
}
Run Code Online (Sandbox Code Playgroud)

我们从未发现它太麻烦,而且我确信这是许多团队使用的确切解决方案。

  • 我理解您的担忧;两行检查抛出实际上占用的行数是单行检查抛出的两倍。然而,我仍然认为两行代码的可读性更高,并且是一种更正统的方法。 (3认同)