繁体   English   中英

在方法重载中引发参数异常

[英]Throwing argument exceptions in method overloads

我最近才开始研究使用例外和最佳做法,但我想知道这样做的正确方法是什么:

假设有一个带有多个参数的方法。 此方法具有较少参数的多个重载,这些重载通过提供默认值来调用主要实现。

是否在每次重载时都验证所有参数?

public string Translate(string text)
{
    if (String.IsNullOrEmpty(text))
        throw new ArgumentNullException();

    return Translate(text, "english");
}

public string Translate(string text, string language)
{
    if (String.IsNullOrEmpty(text))
        throw new ArgumentNullException();

    // Do the rest of the work
    // ...
}

我会抛出异常吗?

public string Translate(string text)
{
    try
    {
        return Translate(text, "english");
    }
    catch
    {
        throw;
    }
}

public string Translate(string text, string language)
{
    if (String.IsNullOrEmpty(text))
        throw new ArgumentNullException();

    // Do the rest of the work
    // ...
}

还是我完全放弃异常并尝试/捕获超载块?

public string Translate(string text)
{
    return Translate(text, "english");
}

public string Translate(string text, string language)
{
    if (String.IsNullOrEmpty(text))
        throw new ArgumentNullException();

    // Do the rest of the work
    // ...
}

另外,这两种方法的文档看起来如何?

(使用C#XML注释。尤其是在放置<exception>元素的位置。)


我的确意识到这只是一个小问题,但每次遇到这种情况(实际上是很常见的)时,我仍然想知道。

可选参数以某种方式解决了这个问题,那么您只有一个方法:

public string Translate(string text, string language="english")

有一些带有可选参数的怪癖很容易了解。

默认值被“烘焙”到调用代码中。 [...]这可能导致公开公共const的问题-如果您更改了库中的默认值,但不重新编译调用代码,则调用代码仍将使用旧的默认值。 使用可选参数设计API时,绝对需要考虑这一点。

让我们列出您所拥有的三个选择的利弊清单,并决定:

1.是否在每次重载时验证所有参数?

优点:您会知道字符串是否为空,然后抛出异常。 经典又好。 缺点:您将在引发异常后调用第二个函数,因为该异常是由于字符串为空或null所致。

所以我会放弃这个想法。

2.我是否抛出异常?

优点:1)这是我个人的最爱,就像您逐行走一样。 调用第二个函数,并在其中引发异常并将其捕获在调用函数的catch中,并完成其他一些工作。 2)使用throw关键字而不是throw ex来确保您的堆栈跟踪是完整的。 3)在调用方处理异常是最佳实践。

缺点:请帮我解决缺点。 我没有找到。

3.还是我完全放弃异常并尝试/捕获超载块?

优点:调用函数中未使用try catch。 不完全是专家,但是,它减少了一些代码。 缺点:没有适当的处理,最佳实践表明我们应该在调用函数处处理异常。

我认为第二种选择是最好的选择。

还有一个我想分享的链接,这真的很有帮助

最佳实践:代码项目链接

请告诉我。

实际上,这是一个传统问题,在加密技术中,最好用所谓的静态工厂方法(通常称为getInstance() ,在该方法中,您将很多问题重构到一个地方。 试图弄清您得到的所有响应变得很讨厌,但是根本不做任何事情都不会丢掉异常,只是针对最终用例进行了大大简化,或者将某些内容记入日志并快速失败,或者确保您处于正常状态。一个学生环境。

我在这里回答很晚,但是我想指出的是,如果您正确地执行了重载,那么这实际上不应该成为问题。 重载的正确方法是将所有功能代码放入接受所有可能参数的方法中:

public string Foo(string param1, string param2, string param3)
{
    // do work here, including throwing argument exceptions
}

然后,您的重载应使用默认值填充缺失的参数:

public string Foo(string param1)
{
    return Foo(param1, null, null);
}

public string Foo(string param1, string param2)
{
    return Foo(param1, param2, null);
}

然后,基于此,您只需要在主要的重载(实际执行填充的异常)中处理异常即可。 请记住,您的重载本身不应该引起异常。 例如,如果通过抛出ArgumentNullException强制param3不为null,则不应为该param传递null ,而应传递一些可以用作默认值的实际字符串。

无论最终调用哪个重载,都将调用主重载(带有引发),并且引发的任何异常都会冒泡至原始代码。 换句话说,您不需要执行以下操作:

public string Foo(string param1)
{
    if (param1 == null)
    {
        throw new ArgumentNullException(nameof(param1));
    }

    return Foo(param1, "param2 default", "param3 default");
}

因为主重载已经进行了检查,并且如果param1为null则将抛出该param1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM