尝试Catch或If语句?

Bac*_*ave 20 .net c# exception-handling

如果你认为有可能获得空指针异常,你应该使用if语句来确保变量不为null,还是应该捕获异常?

我没有看到任何区别,因为你可以把你的逻辑处理if语句或catch块中的空指针,那么哪一个是最好的做法?

log*_*ist 36

我会说总是使用逻辑来捕获异常,而不是尝试/ catch.

在验证时应该使用Try/Catch,但是会发生一些奇怪的事情并且某些事情会导致错误,因此您可以更优雅地处理它.

  • 只是为了补充一点,我认为线索就在名称中,你捕获的异常就是这样,你无法预测或无法处理的代码流的例外.如果逻辑可以处理它也不例外. (7认同)

ang*_*son 18

这里没有单一的答案,这取决于它.

我们来看几个场景让你看看我的意思.

场景:采用不接受的引用类型参数的方法 null

您正在定义一个方法,它需要一个引用类型参数,比如一个流对象,并且您不希望接受它null作为合法的输入参数.

在这种情况下,我会说,合同null不是一个有效的输入.如果某些代码确实使用null引用调用该方法,则合同将被破坏.

这是一个例外,更具体地说,它是一个ArgumentNullException.

例:

public void Write(Stream stream)
{
    if (stream == null)
        throw new ArgumentNullException("stream");
    ...
Run Code Online (Sandbox Code Playgroud)

我肯定不会让代码执行,直到它在这种情况下尝试取消引用流,而不是使用NullReferenceException崩溃,因为在那时我失去了所有能力,当我知道原因.

问:为什么我不能返回false而不是抛出异常?

答:因为返回值很容易被忽略,你真的希望你的"Write"方法只是默默地跳过写入,因为你在调用代码中做了一个snafu,传递了错误的流对象或者无法写入的东西吗?我不会!

场景:方法返回对象的引用,有时没有对象

在这种情况下,合同是null合法的结果.在我看来,null是要避免的,因为很难确保你到处都能正确处理,但有时这是最好的方法.

在这种情况下,我会确保if绕过结果,以确保在null引用返回时我不会崩溃.

概括

如果你仔细看看上面两个场景,你会注意到一件事:

在这两种情况下,它归结为预期的,合同是什么.

如果合同说"不null",则抛出异常.不要回到旧式的API返回方式,false因为不应该忽略异常问题,并且使用if语句乱丢代码以确保每个方法调用成功都不会产生可读代码.

如果合同说" null完全有可能",请用if声明处理.

广告

为了更好地掌握null问题,我还建议您为您和您的团队获取ReSharper,但请注意,此答案可应用于任何类型的异常和错误处理,同样的原则适用.

有了它可以嵌入到项目中的属性来标记这些情况,然后ReSharper将突出显示有问题的代码.

public void Write([NotNull] Stream stream)

[CanBeNull]
public SomeObject GetSomeObject()
Run Code Online (Sandbox Code Playgroud)

要阅读有关ReSharper使用的合同属性的更多信息,请参阅