错误检查的适当量是多少?

发布于 2024-07-07 03:24:08 字数 745 浏览 15 评论 0原文

public void PublicMethod(FooBar fooBar)
{
    if (fooBar == null)
        throw new ArgumentNullException("fooBar", "fooBar cannot be null");

    // log the call [added:  Thanks S.Lott]
    _logger.Log("PublicMethod called with fooBar class " + fooBar.Classification);

    int action = DetermineAction();
    PrivateMethod(fooBar, action);
}

private void PrivateMethod(FooBar fooBar, int action)
{
    if (fooBar == null)
        throw new ArgumentNullException("fooBar", "fooBar cannot be null");  // Is this line superfluous?

    /*
        Do something
    */
}

如果已经在公共接口上检查了输入,是否可以在私有方法中跳过这种错误检查? 通常有一些可以遵循的经验法则...

编辑:

也许 ArgumentNullException 不是一个很好的例子,因为可以提出您应该在两个级别进行检查但返回不同的错误消息的参数。

public void PublicMethod(FooBar fooBar)
{
    if (fooBar == null)
        throw new ArgumentNullException("fooBar", "fooBar cannot be null");

    // log the call [added:  Thanks S.Lott]
    _logger.Log("PublicMethod called with fooBar class " + fooBar.Classification);

    int action = DetermineAction();
    PrivateMethod(fooBar, action);
}

private void PrivateMethod(FooBar fooBar, int action)
{
    if (fooBar == null)
        throw new ArgumentNullException("fooBar", "fooBar cannot be null");  // Is this line superfluous?

    /*
        Do something
    */
}

Is it OK to skip this kind of error checking in private methods if the input is already checked on the public interface? Usually there's some sort of rule-of-thumb one can go by...

Edit:

Maybe ArgumentNullException isn't such a good example because the argument can be made that you should check at both levels but return different error messages.

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

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

发布评论

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

评论(9

忆离笙 2024-07-14 03:24:08

我会说不。

虽然在这种情况中您确实知道它已经被检查过可空性,但两个月后,最年轻的实习生将会出现并编写
PublicMethod2 也调用 PrivateMethod,但是你瞧,他忘了检查 null。

I would say no.

While it certainly holds true that you in this case knows that it has already been checked for nullability, in two months time the youngest intern will come along and write
PublicMethod2 that also calls PrivateMethod, but lo and behold he forgot to check for null.

骄傲 2024-07-14 03:24:08

由于 public 方法并不真正使用 foobar,所以我不确定它为什么要检查。 当前的私有方法关心,但关心是私有方法的责任。 事实上,私有方法的全部意义是将所有职责委托给它。

方法检查它实际使用的输入; 它不会检查它只是经过的东西。

如果不同的子类具有相同的公共方法,但有一些不同的私有方法实现(可以容忍空值),现在该怎么办? 您有一个公共方法,现在对新子类有错误的约束。

您希望在公共方法中做尽可能少的事情,以便各种私有实现可以自由地做正确的事情。 不要“过度检查”或“以防万一”检查。 委派责任。

Since the public method doesn't really use foobar, I'm not sure why it's checking. The current private method cares, but it's the private method's responsibility to care. Indeed, the whole point of a private method is to delegate all the responsibilities to it.

A method checks the input it actually uses; it doesn't check stuff it's just passing through.

If a different subclass has the same public method, but some different private method implementation -- one that can tolerate nulls -- what now? You have a public method that now has wrong constraints for the new subclass.

You want to do as little as possible in the public method so that various private implementations are free to do the right thing. Don't "over-check" or "just-in-case" check. Delegate responsibility.

情绪失控 2024-07-14 03:24:08

我会尽可能地检查错误,你永远不知道什么时候会发生你没有想到的事情。 (安全总比后悔好)

I'd error check everything you can, you never know when something might happen that you didn't think about. (and its better safe than sorry)

往事风中埋 2024-07-14 03:24:08

使用合同设计时 (http://en.wikipedia.org/wiki/Design_by_contract)通常客户端(公共方法)有责任进行正确的调用,即传递有效的参数。 在这个特定的场景中,它取决于 null 是否属于一组有效的输入值,因此有 3 个选项:

1) Null 是有效值:抛出异常或错误将意味着破坏契约,服务器(私有方法)必须处理null 并且不应该抱怨。

2) Null 是无效值,由您控制范围内的代码传递:由服务器(私有方法)决定如何反应。 显然,抛出异常是处理这种情况的更优雅的方式,但它的成本是必须在堆栈的其他地方处理该异常。 异常并不是处理因编程错误而导致违反合同的最佳方式。 你确实应该抛出异常,不是当合同已经被违反时,而是当由于软件无法控制的环境问题而无法履行合同时。 通过将断言插入私有方法的开头来检查参数是否不为空,可以更好地处理错误。 这将降低代码的复杂性,无需处理堆栈上的异常,并且将实现在测试期间突出显示损坏的合同的目标。

3)然后是防御性编程(http://en.wikipedia.org/wiki/Defense_programming)。 当处理由您无法控制的外部代码传递的参数时,代码的直接层需要根据其与外部世界的通信契约运行偏执级别的检查并返回错误。 然后,深入到不对外暴露的代码层,坚持按契约编程仍然更有意义。

When using design by contract (http://en.wikipedia.org/wiki/Design_by_contract) it’s normally client’s (public method) responsibility to make correct invocation, i.e. pass on valid parameters. In this particular scenario it depends whether null belongs to a set of valid input values, therefore there are 3 options:

1) Null is valid value: throwing exceptions or errors would have meant breaking the contract, the server (private method) has to process the null and shouldn’t complain.

2) Null is invalid value and passed by code within your control: it is up to the server (private method) to decide how to react. Obviously, throwing an exception is more graceful way of handling the situation, but it has a cost of having to handle that exception somewhere else up the stack. Exceptions are not the best way to deal with violation of contract caused by programming blunders. You really should throw exceptions not when a contract is already violated but when it cannot be fulfilled because of environmental problems what cannot be controlled in software. Blunders are better handled by sticking an assertion into the beginning of the private method to check that the parameter is not null. This will keep the complexity of your code down, there is no cost of having to handle the exception up the stack and it will achieve the goal of highlighting broken contracts during testing.

3) Then there is defensive programming (http://en.wikipedia.org/wiki/Defensive_programming). When dealing with parameters passed by an external code outside your control the immediate layer of your code needs to run paranoid level of checks and return errors according to its communication contract with the external world. Then, going deeper into the code layers not exposed externally, it still makes more sense to stick to the programming by contract.

热情消退 2024-07-14 03:24:08

至少添加一条注释,指出 PrivateMethod 必须有一个非空 FooBar 并且 PublicMethod 会检查这一点。

At least put a comment that PrivateMethod must have a non-null FooBar and that PublicMethod checks this.

白首有我共你 2024-07-14 03:24:08

您可能还想将“私有”方法标记为私有或受保护。

You might want to also mark the "private" method as private or protected.

长不大的小祸害 2024-07-14 03:24:08

这取决于空值是否表示方法有错误。 请记住,方法也可以称为对象的消息; 它们也对对象的状态进行操作。 参数可以专门指定发送的消息类型。

  • 如果 publicMethod() 不使用参数并更改实例的状态,而 privateMethod() 使用参数,则不要将其视为 publicMethod 中的错误,而应将其视为 privateMethod() 中的错误。
  • 如果 publicMethod() 不改变状态,则将其视为错误。

您可以将后一种情况视为为对象的内部功能提供接口。

That depends if a null-value indicates an error for a method. Remember that methods could also be called messages to an object; they operate on the state of the object aswell. Parameters can specialize the kind of message sent.

  • If publicMethod() does not use a parameter and changes the state of the instance while privateMethod() uses the parameter, do not consider it an error in publicMethod, but do in privateMethod().
  • If publicMethod() does not change state, consider it an error.

You could see the latter case as providing an interface to the internal functioning of an object.

森林很绿却致人迷途 2024-07-14 03:24:08

我认为答案是“是的,再次进行检查”,因为: -

  • 将来可以通过代码的不同路径再次重用私有成员,因此针对这种情况进行防御性编程。
  • 如果您对私有方法执行单元测试,

如果我有一个静态分析器可以检测到这一点并且不标记私有方法中可能使用空引用,那么我的观点可能会改变。

I'd consider the answer to be "yes, do the check again" because:-

  • The private member could be reused again in the future from a different path through the code, so program defensively against that situation.
  • If you perform unit tests on private methods

My view might change if I had a static analyser that could pick this up and not flag the potential use of a null reference in the private method.

路弥 2024-07-14 03:24:08

如果 PrivateMethod 使用已验证的输入频繁调用,而很少使用用户输入调用,那么我将使用 PublicMethod/PrivateMethod 概念,不对 PrivateMethod 进行错误检查(并且 PublicMethod 除了检查参数之外什么也不做)调用 PrivateMethod)

我还会将私有方法称为 PublicMethod_impl (用于“实现”),因此很明显,它是一种内部使用/无检查方法。

我认为这种设计会带来健壮的应用程序,因为它迫使您考虑何时检查什么。 总是检查参数的人常常会陷入“我检查了一些东西,因此我检查了所有东西”的陷阱。

举个例子,一位前同事(用 C 语言编程)在使用指针之前,总是检查它是否为空。 一般来说,他的代码中的指针在启动时就被初始化并且从未改变,因此它为空的可能性非常低。 而且,该指针有 1 个正确值和 65535 个可能的错误值,而他只是检查这些错误值之一。

In cases where PrivateMethod will be called frequently with input that has already been verified, and only rarely with user input, Then I would use the PublicMethod/PrivateMethod concept with no error checking on PrivateMethod (and with PublicMethod doing nothing other then checking the parameters and calling PrivateMethod)

I would also call the private method something like PublicMethod_impl (for "implementation") so it's clear that it's an internal use/ no checking method.

I maintain that this design leads to more robust application, as it forces you to think about what's checked when. Too often people who always check parameters fall into the trap of "I've checked something, therefore I've checked everything".

As an example of this, a former co-worker (programming in C) would, before using a pointer, always check to see if it was null. Generally, the pointers in his code were initialized as startup and never changed, so the chances of it being null were quite low. Moreover, the pointer has one correct value and 65535 possible wrong values, and he was only checking for one of those wrong values.

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