有什么理由抛出 DivideByZeroException 吗?

发布于 2024-08-27 19:12:54 字数 559 浏览 17 评论 0原文

在某些情况下,抛出错误是可以避免的好主意吗?

我正在特别考虑 DivideByZeroExceptionArgumentNullException

例如:

double numerator = 10;
double denominator = getDenominator();

if( denominator == 0 ){
   throw new DivideByZeroException("You can't divide by Zero!");
}

是否有任何原因引发这样的错误?

注意:我不是在谈论捕获这些错误,而是特别了解是否有抛出这些错误的充分理由。

重申一下

我知道在我给出的示例中,处理错误可能会更好。也许这个问题应该重新表述。是否有任何理由抛出其中一个错误而不是在位置处理它。

Are there any cases when it's a good idea to throw errors that can be avoided?

I'm thinking specifically of the DivideByZeroException and ArgumentNullException

For example:

double numerator = 10;
double denominator = getDenominator();

if( denominator == 0 ){
   throw new DivideByZeroException("You can't divide by Zero!");
}

Are there any reasons for throwing an error like this?

NOTE: I'm not talking about catching these errors, but specifically in knowing if there are ever good reasons for throwing them.

JUST TO REITERATE:

I KNOW that in the example I gave you'd probably be better off handling the error. Perhaps the question should be rephrased. Are there any reasons to throw one of these errors instead of handling it at this location.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

深居我梦 2024-09-03 19:12:54

假设您编写了一个库来处理不适合 Int64 的大整数,那么您可能希望为您编写的除法算法抛出 DivideByZeroException 。

Let's say you write a library to work with really big integers that don't fit into Int64, then you might want to throw DivideByZeroException for the division algorithm you write.

小耗子 2024-09-03 19:12:54

.NET 运行时已经非常擅长抛出这些异常。它们也对错误进行了高度描述,您无法向异常消息添加任何好的注释。 “你不能除以零”没有任何价值。

但是,您可以通过筛选客户端代码传递的值来避免许多此类异常。如果客户端代码传递了 null,则您将需要 ArgumentNullException 与参数名称,而当它传递可能导致 DivideByZero 错误的内容时,您将需要 ArgumentException。

The .NET runtime is already very good at throwing these exceptions. They are also highly descriptive of what is wrong, you can't add any good commentary to the exception message. "You can't divide by zero" adds no value.

However, you can avoid many of these exceptions by screening the values passed by the client code. You'll want ArgumentNullException with the name of argument if the client code passed a null, ArgumentException when it passed something that is liable to trip DivideByZero.

昔梦 2024-09-03 19:12:54

这样做绝对是有原因的,并且与大多数抛出异常的问题一样,您必须将自己视为在团队中工作的开发人员。您正在编写的内容可能是另一个系统的一部分,也可能是一个库或组件。

如果您编写了一个数学库,并且有一个名为 Divide(int a, int b) 的函数来将它们相除,如果其他人想要使用您的方法并传入零,您将需要抛出这是一个例外,因此作为开发人员,他们知道自己搞砸了。

如果不抛出异常,就会在代码中引入错误。如果我使用你的除法,并输入值 10 和 0,这将产生 10/0 并因此出现异常,唯一正确的答案是错误。如果您决定更改值以便不发生错误或返回 0,则这不是我所期望的 - 我认为我的除法工作完美,并且从未注意到问题。我很可能会取这个 0 并在其他计算中使用它,而没有意识到这是错误的答案,因为 10/0 不是 0。

There is absolutely a reason to do this, and as with most exception throwing questions, you have to think about you as a developer working in a team. What you're writing may be part of another system, or it may be a library or component.

If you write a maths library , and have a function called Divide(int a, int b) that divides them, if someone else wants to use your method and passes in zero, you'll want to throw an exception so they, as a developer, know they've screwed up.

If you don't throw an exception, you introduce bugs into your code. If I used your divide method, and put the values 10 and 0 in, which produces 10/0 and thus an exception, the only correct answer is error. If you decide to change the values so no error occurs, or return 0, that is not what I am expecting - I assume my division worked perfectly, and never notice a problem. I might well take that 0 and go off and use it in other calculations, unaware that it's the wrong answer, because 10/0 is not 0.

戏舞 2024-09-03 19:12:54

您应该只使用异常来处理异常情况。

在这种情况下,看起来零是无效的用户输入。您应该检查无效的用户输入,并在之前进行相应的处理,直到出现异常为止。

只要正确处理输入,就不会发生 DivideByZeroException。如果即使在验证输入后您也收到 DivideByZeroException...那么您就知道您遇到了真正的问题(在这种情况下,异常是适当的)。

You should only use an Exception to handle Exceptional cases.

In this case, it looks like a zero would be invalid user input. You should check for invalid user input and handle it accordingly BEFORE you get to the point that an Exception would be approriate.

As long as you properly handle input, there should be no reason for a DivideByZeroException to happen. If you receive a DivideByZeroException even after validating input...then you know you have a real problem (in which case, the Exception is appropriate).

凤舞天涯 2024-09-03 19:12:54

如果您谈论的是直接与 UI 交互的代码,那么不行。我想不出你想要这样做的任何理由。

但是,如果您正在构建其他开发人员使用的类/对象,并且他们传递了明显愚蠢的数据,那么在验证期间会抛出适当的错误。

If you're talking about code that is directly interacting with the UI, then no. I can't think of any reason why you'd want to.

However, if you're building a class/object used by other devlopers and they've passed in data that is clearly stupid then throw the appropriate error during your validation.

半窗疏影 2024-09-03 19:12:54

如果您正在编写 BigInteger 库,那么您绝对应该抛出适当的 DivideByZero 异常。如果您正在编写一个购物车库,那么......呃,可能不会。

目前,我想不出抛出 NullReferenceException 的好理由。如果您创建的 API 的文档显示“HummingBirdFeeder.OpenSugarWaterDispenser(Dispenserdispenser, int flowRate) 的第一个参数是您要打开的糖水分配器”。如果有人出现并将 null 值传递给此方法,那么您绝对应该抛出 ArgumentNullException

不过,从 API 中释放 NullReferenceException 只不过是一种懒惰行为,因为这是错误的,而且会泄露一些内部信息。

编辑添加:

现在您将问题更改为引用 ArgumentNullException 那么答案很简单:是的,在这种情况下您绝对应该抛出这种异常:

  • 您正在编写一个公共方法。
  • 为参数获取空值在某种程度上是不合适的(即,如果没有该特定参数,该方法就没有意义)。
  • 该方法的文档表明不允许使用空值。

在这种情况下,您的方法应该做的第一件事是检查空值,如果违反条件则抛出异常。

如果您正在编写私有或内部方法,那么在大多数情况下,您不需要在发布版本中的运行时验证参数。您可以确保您自己的代码正确调用您自己的代码。有助于创建这种保证的一件事是通过添加断言来验证调试构建中的参数:

Debug.Assert(dispenser != null);

这样您就可以验证代码是否正确运行并尽早捕获任何错误,而不会因为一堆无用的冗余而减慢发布的代码的速度检查。

If you're writing a BigInteger library, then you absolutely should throw an appropriate DivideByZero exception. If you're writing a shopping-cart library, then...eh, probably not.

I can't, at the moment, think of a good reason to throw a NullReferenceException. If you're create an API with documentation that says "The first parameter to HummingBirdFeeder.OpenSugarWaterDispenser(Dispenser dispenser, int flowRate) is the sugar-water dispenser that you wish to open." And if somebody then comes along and passes a null value to this method, then you should definitely throw an ArgumentNullException.

Letting a NullReferenceException out of your API would just be lazyness, though, because that's wrong and it leaks some of your internals.

EDITED TO ADD:

Now that you changed the question to refer to an ArgumentNullException then the answer is easy: yes, you should definitely throw that kind of exception under these circumstances:

  • You are writing a public method.
  • Getting a null value for the argument is in some way inappropriate (i.e., the method makes no sense without that particular argument).
  • The documentation for the method indicates that null values are not allowed.

In that case, the very first thing your method should do is check for a null value and throw an exception if the condition is violated.

If you are writing a private or internal method, then in most cases you would not need to validate the parameters at runtime in the release build. You can make sure that your own code calls your own code correctly. One thing that helps to create that assurance is to validate the parameters in the debug build by adding assersions:

Debug.Assert(dispenser != null);

This way you can verify that the code is acting correctly and catch any errors earlier without slowing down the released code with a bunch of useless, redundant checks.

冷清清 2024-09-03 19:12:54

在你自己的代码中,我怀疑会有多大用处。但是,如果您正在编写一个将被其他人使用的库,那么您应该使用异常作为将错误传达回使用您的库的代码的方法。

“在框架中,使用了异常
对于硬错误和逻辑错误
错误。一开始可能会很困难
将异常处理视为
报告所有功能的方法
失败。然而,重要的是
设计a的所有公共方法
报告方法失败的框架
抛出异常。”

Krzysztof Cwalina,设计可重用框架

In your own code, I doubt there would be much use. However, if you are writing a library that will be consumed by others then you should use exceptions as the means of communicating errors back to the code consuming your library.

"In the Framework, exceptions are used
for both hard errors and logical
errors. At first, it can be difficult
to embrace exception handling as the
means of reporting all functional
failures. However, it is important to
design all public methods of a
framework to report method-failures by
throwing an exception."

Krzysztof Cwalina, Designing Reusable Frameworks

羁绊已千年 2024-09-03 19:12:54

这里的标题有点误导,它不是抛出(特殊)DivideByZeroException 而是问题:

验证用户输入时是否应该使用异常?

这可能以前已经被问过。我的看法:不,只需使用一个流程,让您可以通过错误代码或布尔值来处理此问题。

然而,当验证应用程序更深层的“数据”时,抛出异常通常是正确的做法。

Slightly misleading title here, it is not about throwing the (special) DivideByZeroException but rather the question:

Should I use exceptions while validating user input?

This has probably been asked before. My take: No, just use a flow that lets you handle this with error codes or booleans.

However, when validating 'data' in deeper layers of an app, throwing an exception is usually the right thing to do.

双手揣兜 2024-09-03 19:12:54

如果您正在编写某种形式的数字类,并且可以预期调用您的类的代码已执行验证,那么我可以看到抛出 DivisionByZeroException 可能有用,但在几乎任何其他情况下,最好在操作之前进行检查并抛出以及 ArgumentException 或 ArgumentOutOfRange 异常(视情况而定)。

NullReferenceException 是框架使用的保留异常之一,您永远不应该通过公共 API 抛出它,另外还有 IndexOutOfRange、AccessViolationException 和 OutOfMemoryException。请参阅《框架设计指南》一书或 代码分析警告解释

If you were writing a numerical class of some form and can have expected the code calling your class to have performed the validation then I can see it might useful to throw DivisionByZeroException but in almost any other case it would better to check before the operation and throw and ArgumentException or ArgumentOutOfRange exception as appropriate.

NullReferenceException is one of the reserved exceptions that the framework uses that you should never throw through a public API, along with IndexOutOfRange, AccessViolationException and OutOfMemoryException. See the Framework Design Guidelines book or the Code Analysis warning explanation

你好,陌生人 2024-09-03 19:12:54

我想不到。我只会针对它进行编程。异常的代价可能很高,因此,如果您可以针对异常进行防御性编程,那就这样做,而不是抛出异常。

至少这是我的高级开发人员在很多个月前尝试捕获 DivideByZeroException 时告诉我的。

None that I can think of. I would just program against it. Exceptions can be expensive, so if you can defensively program against it, do that instead of throwing an exception.

At least that's what my senior dev told me when I tried catching a DivideByZeroException many moons ago.

如何视而不见 2024-09-03 19:12:54

在开始处理数据之前,最好在函数顶部进行这些检查。而不是在方法中间抛出它们(或任何其他方法抛出这些异常)。

Its a good practice to make these checks at top of the function before you start processing data. Rather then throwing them (or any other method throws these exceptions) in the middle of a method.

山川志 2024-09-03 19:12:54

从理论上(以及实践)来看,识别并避免/消除错误情况比将它们视为异常要好。但是,并不总是可以测试代码中的每个情况或路径 - 这也是不可能的在每种情况下控制您的输入。

良好设计的原则是让您的程序识别并优雅地处理异常情况。此外,最好为您的用户(最终是您自己)提供足够的信息来诊断错误 - 特别是那些可能发生的错误部署代码后。因此,有时抛出异常(例如所示的异常)确实是有意义的,如果它会使您的应用程序代码更健壮且更易于诊断。

In theory (and practice too), identifying and avoiding/eliminating erroneous cases is better than treating them as exceptions. However, it's not always possible to test every case or path through your code - it's also not possible in every case to control your inputs.

A tenet of good design is to have your program recognize and gracefully handle exceptional situations. Furthermore, it's a good idea to provide your users (and ultimately yourself) enough information to diagnose errors - particularly those that can occur after your code is deployed. Therefore, it does sometimes make sense to throw exceptions such as the kind illustrate if it will make your application code more robust and easier to diagnose.

虚拟世界 2024-09-03 19:12:54

从不(用户永远不会发送 0 作为分母)和总是(用户将始终提供适当的参数值)是在代码中包含的危险想法。我们中只有极少数人单独编程,编写的代码永远不会被其他开发人员修改或调用。所以,我们需要编写防御代码。在除以零的情况下,我不应该决定适当的结果应该是什么,这取决于调用者。抛出异常似乎是交回问题的合理方法。虽然涉及费用,但我添加到代码中以避免引发异常的任何基础设施也会增加费用。

Never (the user will never send 0 as the denominator) and always (the user will always provide appropriate argument values) are dangerous ideas to include in your code. A very small percentage of us program alone, on code that will never be modified or called by another developer. So, we need to write defensive code. In the case of division by zero, I should not be deciding what the appropriate result should be, that falls back on the caller. Throwing the exception seems like a reasonable way to hand the issue back. While there is expense involved, any infrastructure I add to my code to avoid throwing the exception also adds expense.

冷夜 2024-09-03 19:12:54

考虑到对于双精度数,除以零实际上会产生一个值:double.Infinity、double.NegativeInfinity 或 double.NaN,分别取决于分子是正数、负数还是零。

这些值可能已经适合您的情况,如果不是,您可能需要在执行除法之前验证输入并采取相应的操作。

如果您正在编写一个 API(例如在库上)并希望提供一个不允许除以零的合约(假设它公开了执行某种除法的方法),那么您可能需要抛出此异常。但通常情况下,我会保留这种类型的异常作为程序错误的指示。

Consider that for doubles, a division by zero will actually result in a value: double.Infinity, double.NegativeInfinity or double.NaN, depending upon whether the numerator is positive, negative or zero, respectively.

It may be that these values are already suitable for your case, if not you will probably want to validate the input, and act accordingly, before you perform the division.

If you are writing an API (such as on a library) and want to provide a contract that disallows a division by zero (say it exposes method that performs some kind of division) then you may want to throw this exception then. Typically though, I would reserve this type of exception as an indicator of a programmatic error.

风流物 2024-09-03 19:12:54

如果您依赖框架来完成工作(.NET 或其他框架),那么您应该让框架抛出异常

这将使使用者更容易处理以标准方式抛出的异常的方法。

在除以零的情况下,您只需重新实现与框架中相同的逻辑来引发异常。

If you are relying on a framework to do the work (.NET or otherwise), then you should let the framework throw the exception.

This will make it easier for consumers of your methods to handle exceptions that are thrown in a standard way.

In the case for dividing by zero, you are just re-implementing the same logic to throw an exception as in the framework.

落墨 2024-09-03 19:12:54

从资源的角度来看,抛出异常是一件昂贵的事情。您已经阻止了异常的发生,那么为什么还要抛出异常呢?如果您必须告诉用户,请使用某种消息传递机制。如果您需要自己了解,请记录下来。

Throwing an exception is an expensive thing to do from a resource point of view. You have already prevented an exception from occurring so why throw one? If you have to tell the user, use some messaging mechanism. If you need to know about it yourself, log it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文