返回包含信息的成功指示器
本文关键字:成功 指示器 信息 包含 返回 | 更新日期: 2023-09-27 18:27:55
我目前正在构建一个API,它执行某个操作,该操作应指示该操作是否成功。我还需要知道,如果行动失败了,为什么会失败。我应该如何实现这一点?当发生错误时,我应该使用void返回类型并抛出异常吗?还是应该返回bool和某种消息来指示它失败的原因?
确定这种情况发生的频率,如果答案是经常发生的,请考虑使用字符串引用参数来获取消息和具有布尔返回值的方法。
或者,只需要一个返回字符串的字符串返回值。如果成功则清空,只需检查它的长度即可知道它是成功还是失败。
第三种选择是像另一个回答者所说的那样返回一个枚举,这将表明它的原因,但不能保存来自另一个异常等的任何信息。
如果很少发生,则抛出异常。
在我看来,无效和异常应该是可以的。
如果失败,异常消息应该足以告诉您发生了什么。
如果成功了,那就继续你的快乐之路吧。
如果一个方法通常会被预期特定失败场景并能够处理它的代码直接调用,那么该方法应该通过抛出异常以外的一些方式来区分成功或预期失败场景。请注意,调用方不是所期望的失败场景在任何情况下都应该引发异常。如果某些调用代码不期望出现特定的失败场景,但其他代码会出现,那么有两个版本的方法可能会有所帮助——其中一个在问题场景中抛出异常,另一个返回其他类型的错误指示。
Microsoft库中使用的一种常见模式是有一对方法,使用命名模式DoSomething
和TryDoSomething
。如果失败,DoSomething
方法将抛出异常。它应该提供给调用者的任何数据都将在返回值中指示。第二种方法将返回指示操作是否成功的bool
值;呼叫方的任何数据都将通过CCD_ 5参数来指示。当微软开始使用这种方法时,这种方法可能是合理的,但它与后来添加的语言功能交互不好。除其他外:
-
像
IEnumerable<T>
这样只对函数返回值使用类型参数的接口被允许相对于该类型是协变的(允许期望例如IEnumerable<Animal>
接受IEnumerable<Cat>
的代码)。然而,对于out
参数,协方差不起作用。如果模式是例如T TryGetSomething(ref bool Success)
而不是bool TryGetSomething(ref T Result)
,则协方差可以用于"尝试"方法。 -
VB.NET和C#都允许声明和赋值变量的语句根据赋值表达式推断类型。尽管这可以很好地用于返回值提供数据的方法,但它不能用于通过
out
参数将数据提供给调用方的方法。
除了这些限制之外,Microsoft模式可能不太适合您的场景,因为它不包括无法指示其原因的函数的机制。此外,虽然Microsoft建议不要使用一种基于传入参数可以充当DoSomething
和TryDoSomething
的方法,同时使用一种方法有一个主要优点:如果一个操作需要多个子操作,这些子操作可能成功或失败,并且如果任何部分的失败意味着整个操作的失败,则可能希望内部方法中的失败在从DoSomething
调用时抛出异常,但在从TryDoSomething
调用时返回错误代码。使用内部方法的单独"throw"或"don't throw"变体需要复制调用它们的代码——这太恶心了。
因此,我建议您可能想要定义一个INotifyOfFailure
接口,并让您的方法采用可选的INotifyOfFailure
参数(默认为null)。如果发生故障,并且INotifyOfFailure
参数不为空,则调用其上的方法通知其故障;它可以在内部存储有关故障的信息;函数返回后,它可以询问传入的对象操作是否成功。
bool
可能是最好的消息。最终,异常是昂贵的——无论是API处理还是客户端处理——所以最好完全避免它们,并使用前面提到的bool
和string
之类的构造。
如果发生异常,即意外情况,则应抛出异常。
另一种选择是使用enum
,这样您就可以返回不同的结果。类似的东西
public enum Results
{
Error,
Warning,
Minor,
}
然后他们可以使用
var result = YourApiCall();
if (result == Result.Error)
// Do something
您可以创建一个从EventArgs
派生的类,并添加一个Boolean
属性来检查错误,如果true具有String
属性,则可以从中获取错误消息。