1

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

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 
    }
}
4

6 回答 6

1

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

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

于 2010-01-25T12:48:54.243 回答
0

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

于 2010-01-25T11:43:48.340 回答
0

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

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

于 2010-01-25T20:17:56.730 回答
0

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

在这些情况下,当事情没有按照您期望的那样发展时,您希望被告知。

然而,在生产环境中,您可能不想通过调用形状集合中不存在的成员来破坏整个应用程序。

于 2010-01-25T10:04:28.990 回答
0

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

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

于 2010-01-25T19:25:13.453 回答
0

我建议答案是......像往常一样......“这取决于”。虽然在 IEnumerable 上调用 Any 并不昂贵,但真的有必要吗?这取决于您计划在该方法中对您的收藏做什么。

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

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

于 2010-01-25T19:33:30.217 回答