错误处理:使用try-catch还是返回错误代码?

3

我认为我已经理解了,但需要您的进一步确认,因为我想正确地理解并执行!在抽象化异常处理和逻辑代码方面,我仍然没有找到一个直线。所以我想在您的帮助下更加接近它。

让我们考虑我调用函数"foo(0)":

// Code 1
int foo(int a)
{
    int value = 10;
    return value/a;
}

这将抛出“除以零”的异常。

但是,如果参数"a"必须在函数"bar"(代码2)能够返回有效结果的特定范围内(例如在[5...10]的范围内),那么使用超出该范围的值(例如3)调用它当然不会引发异常,除非我定义一个异常。因此,针对这种情况,我要定义一个异常,是吗?

例如,可以这样做:

// Code 2
void bar(int b)
{
    if (b < 5)
    {
        throw new ArgumentException("Your input parameter is below minimum acceptable value");
    }
    else if (b > 10)
    {
        throw new ArgumentException("Your input parameter is above maximum acceptable value");
    }
    else
    {
        output(b);
    }
}

那么,难道不应该使用异常来处理这个问题吗(我认为它们正是为了这个目的而存在),我更倾向于用这种方式解决问题?

// Code 3
int bar(int b)
{
    int error = 0

    if (b < 5)
    {
        error = -1;
    }
    else if (b > 10)
    {
        error = -2;
    }
    else
    {
        output(b);
    }

    return error;
}

感谢您的意见。

祝好!

我询问的原因是,我手头有一份已发布软件的源代码,其中包括try-catch。由于我在OOP方面没有太多经验,因此也不熟悉“try-catch”。根据我找到的帖子和观看的YouTube教程,我认为这个主题非常容易误解。我猜想这个软件的开发人员可能也误解了它。如果我错了,请告诉我。

4个回答

2

在C#中报告错误的惯用方法是抛出异常。当然,返回错误代码在技术上也可以工作,但这不是C#中的惯用方式。


2
"ErrorCodes" 也会带来所谓的 "文档噩梦"。 - Rahul

1

为什么不使用错误码(int bar(int b) {...}),而是使用异常?原因有两个:

  1. 你可以轻易且无意地忽略返回的错误码;调试起来可能会很痛苦。如果抛出异常,你会立刻知道它(程序崩溃)。
  2. 3-14 这样的错误码提供了非常少的信息;异常可以告诉我们很多关于问题的原因:至少包括异常类型(问题是什么;这里有一个 ArgumentOutOfRangeException - 方法的参数超出范围)、消息(问题的描述)和堆栈跟踪(问题在哪里)。

我建议使用稍微不同的代码:

void bar(int b)
{
    // Validation

    if (b < 5)
        //DONE: not just ArgumentException, but ArgumentOutOfRangeException
        //DONE: nameof(b) - which argument has wrong value (useful if you have several arguments) 
        //DONE: when complaining for below/above I suggest developer to know the boundaries 
        throw new ArgumentOutOfRangeException(
            nameof(b), 
          $"Your input parameter b = {b} is below minimum acceptable value {5}");
    else if (b > 10)
        throw new ArgumentOutOfRangeException(
            nameof(b), 
          $"Your input parameter b = {b} is above maximum acceptable value {10}");

    // Argument(s) is / are valid, main routine here

    output(b);
}

谢谢Dmitry提供的代码建议和您添加的宝贵注释! - RadioMan85

1

应该通过抛出适当类型的错误来返回错误(我个人认为)。这样可以明确地通知调用者并处理异常。

示例代码“code 3”中的代码让我感到担忧。它将调用代码与此方法耦合在一起,以根据返回值知道该做什么。没有任何指示表明返回是一个错误,并且它将操作输入值。尽可能明确。


0

你可以在调用方法中使用 Checked Exception 特性来按照它们的类型处理异常。以下 Nuget 包将此特性添加到 C# 语言中。 Portia.Roslyn.CheckedException


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接