在启发式无法访问的代码中扔出是否危险

本文关键字:是否 危险 代码 启发式 访问 | 更新日期: 2023-09-27 18:31:47

我有一个方法,由于一些非直观的业务需求,需要大量的注释。 我不得不重构它以使其不那么简洁(分解?),但是当我说我评论以下方法的地方是必要的,以确保业务需求不会意外更改时,请相信我:

public bool CheckBasedOnApplicableConditions()
{
    bool conditionOne;
    bool conditionTwo;
    // Comments to explain why BusinessLogic is used
    if (BusinessLogic())
    {
        //Comments discussing SecondaryBusinessLogic
        conditionOne = true;
        conditionTwo = SecondaryBusinessLogic();
    }
    else
    {
        //Comments discussing this scenario
        conditionOne = DifferentBusinessLogic();
        conditionTwo = !conditionOne;
    }
    //Comments about the CheckForCondition calls
    if (conditionOne && CheckForConditionOne())
    {
        return true;
    }
    if (conditionTwo && CheckForConditionTwo())
    {
        return true;
    }
    return false;
}

我真的很想让这种方法在未来证明不会被开发人员(也就是我在一个月内)破坏。 我觉得重要的是要强调业务需求包括必须检查两个条件中的至少一个。 所以我在最终返回之前添加了以下代码:

    //ReSharper normally points out this always evaluates to false,
    // but because an exception is being thrown it does not complain.
    if (!conditionOne && !conditionTwo)
    {
        throw new InvalidOperationException
            ("Condition One or Two must be applicable!");
    }

预期效果是,如果开发人员不小心违反了业务需求,则会引发异常,而不是静默返回 false 并创建需要时间跟踪的错误。 这不是我以前真正见过的模式,但是当添加抛出时,ReSharper自动抑制了自己的"代码在启发式上无法访问"警告。

我的问题是:这种方法是否有意想不到的副作用? 即性能损失,或我视而不见的可维护性问题,或其他意外情况? 我知道我可以重构该方法以使其更稳定;但我担心这将以理解为代价。

在启发式无法访问的代码中扔出是否危险

自检代码在某种程度上是可以的,我建议在这里System.Diagnostics.Debug.Assert()

但是验证这种逻辑条件最好通过外部测试来处理,即单元测试或(尚未非常成熟的)代码合约。

由于您只能测试方法的结果,因此这将是将其重构为更小部分的参数。

Henk 的回答让我朝着正确的方向前进:我如此专注于重构这一种方法,以至于我没有想到这实际上需要两个独立的方法。

现在我得到了:

public IEnumerable<Condition> DetermineConditionsToTest()
{
    //determine what conditions to return
}
public bool CheckIfAnyConditionIsMet(IEnumerable<Condition> conditionsToCheck)
{
    // check if any condition is met.
}

现在我为每个单元测试。 教训是:如果你认为你不能对某些东西进行单元测试;继续分解它,直到你可以。