我应该冗余地测试参数(例如集合空虚)吗?

时间:2010-01-25 09:45:45

标签: c# coding-style assert

这里的冗余收集检查有问题吗?:

SomeMethod()
{
    shapes = GetShapes();
    //maybe Assert(shapes.Any())?
    if(shapes.Any())
    {
        ToggleVisibility(shapes);
    }
}

ToggleVisibility(IEnumerable<Shape> shapes)
{
    //maybe Assert(shapes.Any())?
    if(shapes.Any())
    {
        //do stuff 
    }
}

6 个答案:

答案 0 :(得分:1)

我不认为这里有一个大问题,因为调用Any()并不是一项昂贵的操作。

有一个小问题,即未声明ToggleVisibility的责任和行为。如果形状为空或为null,则ToggleVisibility应该让调用者知道它将如何表现。执行此操作的最佳方法是通过XML注释,以便它显示在Intellisense中。这将让ToggleVisibility调用者决定是否需要检查集合是否为空或为空。

答案 1 :(得分:0)

如果您要添加这些断言以进行测试和调试,那么这是有道理的。

在这些情况下,你希望当事情没有像你期望的那样时被告知。

然而,在生产中,您可能不希望通过调用形状集合中不存在的成员来处理整个应用程序。

答案 2 :(得分:0)

您可以使用Code Contract库。在这种情况下,您可以在代码中动态配置前置条件(验证传入值),后置条件(验证结果)和不变量(对于特定类必须始终为true的条件)。

答案 3 :(得分:0)

我认为这里的关键是了解责任。如果你知道每个地方都会调用ToggleVisibility并且打算总是先检查一下,那么可以不检查ToggleVisibility方法。

就我而言,我会在ToggleVisibility中检查它,因为它使调用者代码更清晰,如果你从50个不同的地方调用ToggleVisibility函数,那么你的代码就会少得多。

答案 4 :(得分:0)

我建议答案是......像往常一样......“这取决于”。虽然在IEnumerable上调用Any并不昂贵,但它真的有必要吗?这取决于您计划在方法中对集合进行的操作。

由于空集合,您的方法会抛出异常或其他不受欢迎的东西吗?你是否正在用foreach迭代你的收藏?如果是这样,那么拥有空集合不一定会造成任何伤害,尽管它可能违反您的业务规则。尝试迭代 null 集合显然是不同的。

您使用GetShapes()作为答案的示例框架。为了扩展我的想法,ToggleVisibility()对空集合真的是非法的吗?它显然不会做太多,但如果用户突出显示一组空的形状,然后单击切换可见性功能,它会做什么坏事吗?

答案 5 :(得分:0)

如果ToggleVisibility(IEnumerable<Shape>)是私有方法(因此SomeMethod()必须在同一个库中),那么我肯定只会在Release版本中包含一次检查。检查是采用一种方法还是另一种方法取决于对正在发生的事情有何意义。如果在正确的执行中期望集合永远不会为空,那么可能不需要检查。如果从十个不同的地方调用ToggleVisibility(IEnumerable<Shape>),并且其中任何一个可能都有一个空的集合,那么我肯定会减轻调用者每次进行检查的负担,并且只是将其粘贴在方法本身中。

如果ToggleVisibility(IEnumerable<Shape>)是公共API的一部分,那么它肯定应该进行任何必要的参数验证,因为API的用户可能会做任何事情,并且必须始终检查所有参数。如果该方法的文档声明将忽略空集合,那么SomeMethod()显然不需要担心它。否则,SomeMethod()需要做任何事情来验证它传递的集合是否有效,即使这意味着进行了冗余检查。