[英]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>
元素的位置。)
我的确意识到这只是一个小问题,但每次遇到这种情况(实际上是很常见的)时,我仍然想知道。
让我们列出您所拥有的三个选择的利弊清单,并决定:
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.