我刚开始撇'调试MS。网2.0的应用程序,由约翰*罗宾斯,并已成为混淆了他的布道用于调试。Assert(...).

他指出,良好实施的称存储状态,有些错误的条件,例如:

Debug.Assert(i > 3, "i > 3", "This means I got a bad parameter");

现在,就个人而言,这似乎疯狂,我认为他那么爱重申他的测试没有一个实际合理的商业逻辑的'评论,也许是"我 <=3必须永远不会发生,因为flobittyjam widgitification进程"。

因此,我认为我得到的声称作为一种低水平"让我们保护我的假设"的事情...假定一个感觉这是一个测试一个只需要做在调试-即你们保护自己反对的同事和未来的程序员,并希望他们实际测试的东西。

但我不明白的是,他接着说,应当使用主张在除了正常的错误处理;现在我设想是这样的:

Debug.Assert(i > 3, "i must be greater than 3 because of the flibbity widgit status");
if (i <= 3)
{
    throw new ArgumentOutOfRangeException("i", "i must be > 3 because... i=" + i.ToString());
}

有什么我获得了通过调试。Assert重复的错误的条件测试?我想我会得到它,如果我们谈论的是调试-只有双重检查的一个非常重要的计算...

double interestAmount = loan.GetInterest();
Debug.Assert(debugInterestDoubleCheck(loan) == interestAmount, "Mismatch on interest calc");

...但我不得到它参数的测试,它肯定是值得检查(在两个调试和发布建立)...或者不是。我是什么丢失?

有帮助吗?

解决方案

断言是不进行参数检查。参数的检查应该总是完成(和正是根据什么先决条件是指定的,在你的文件和/或说明书), ArgumentOutOfRangeException 抛出必要的。

断言是为测试"不可能"的情况,即,事情,你(在你的程序逻辑) 假设 是真实的。这些断言是要告诉你,如果这些假定是打破对于任何理由。

希望这可以帮助!

其他提示

有一个通信方面声称vs例外投掷。

让我们说,我们有一个用户类别与一名财产和ToString方法。

如果ToString是实现这样的:

public string ToString()
{
     Debug.Assert(Name != null);
     return Name;
}

它说这个名字不应该空,并有一个错误的用户类别,如果它是。

如果ToString是实现这样的:

public string ToString()
{
     if ( Name == null )
     {
          throw new InvalidOperationException("Name is null");
     }

     return Name;
}

它说,呼叫者是使用ToString不正确,如果名字是空和应该检查之前的呼叫。

执行与两个

public string ToString()
{
     Debug.Assert(Name != null);
     if ( Name == null )
     {
          throw new InvalidOperationException("Name is null");
     }

     return Name;
}

说,如果名字是空有错误的用户类别,但是我们要处理它了。(用户不需要签名称之前的呼叫。) 我认为这是一种安全的罗宾斯是推荐。

我已经想过这个漫长而艰难的时候提供指导,在调试与主张相对于测试问题。

你应该可以测试你的类错误输入,糟糕状态、无效秩序的操作和其他任何可以想象的错误的条件,并断言应该 从来没有 旅行。每个断言是检查的东西应该 总是 是真的不管输入或计算的执行。

好规则的拇指,我已经到了:

  1. 声称是不能替代强大的代码功能的正确的独立的配置。他们是互补的。

  2. 声称不应该被绊倒在一个单元运行测试,甚至当喂养无效值的或测试的错误的条件。该代码应该处理这些条件没有一个断言的发生。

  3. 如果一个断言的旅行(不论是在一个单元测试或检验期间的),该类被窃听。

对于所有其他错误--通常下降到环境(网络连接失去)或滥用(呼叫者通过了一null value)--这是更好的和更可以理解的使用硬检查&例外情况。如果出现异常时,该呼叫知道这是有可能的是他们的错。如果发生断言,呼叫知道这可能是一个错误代码中的断言。

关于重复:我同意。我不明白为什么你会复制验证有一个调试。维护和异常检查。它不仅加入了一些噪声的代码和浑浊的水域对于是谁的错,但是这一形式的重复。

我使用明确的检查扔例外 公共受保护的 方法和断言,私人的方法。

通常,明确的检查警卫队的私有方法看到的不正确的价值观。所以,真正的主张为检查的一个条件,这应该是不可能的。如果一个声称没火,它会告诉我还有一个缺陷在验证逻辑包含在一个公共程序上的类。

一个例外可以被抓住和吞下作出的错误看不到检测。这不可能发生的与调试。断言。

没有人应该永远具有赶上处理程序,捕获所有的例外,但人们这样做,无论如何,有时这是不可避免的。如果你的代码是援引自COM,互操作层捕捉所有的例外情况,并把它们变成COM错误代码,这意味着你不会看到你的未经处理的例外情况。声称不会遭受这一点。

也时唯一的例外将是未处理,仍有更好的做法是采取一个小型垃圾场。一个区域VB更强大的比C#是你可以用一个例外过滤器以捕捉迷你甩的时候唯一的例外是在次飞行,其余的留的异常处理不变。 格雷格Miskelly的博客上的例外过滤器中注入 提供了一个有用的方式做到这一从c#。

一个其他注资产...他们inteact差单元测试的错误的条件下在你的代码。它是值得的,向有一个包装要关闭主张为单元测试。

海事组织这一损失的发展。适当地实施的例外给你一个清晰的画面发生了什么事。我看到了 太多 显示的应用程序模糊"的断言失败:我 < 10"错误。我看到的断言作为一个临时的解决方案。在我看来没有主张应该是在一个最终版本的程序。在我的做法我曾断言,为快速和肮脏的检查。最终版本,该代码应采取错误的情况下入帐户和相应的行为。如果有什么不好的事情发生你有2个选择:处理它离开它。功能应该把一个异常有意义的描述如果是错误的参数。我没有看到有点重复验证的逻辑。

例的一个良好的使用的断言:

Debug.Assert(flibbles.count() < 1000000, "too many flibbles"); // indicate something is awry
log.warning("flibble count reached " + flibbles.count()); // log in production as early warning

我个人认为,应该断言 可以当你知道的东西是之外 希望 限制,但可以肯定这是合理的安全继续。在所有其他情况下(觉得免费指出的情况下,我没有想到的)使用异常的失败硬和快速。

关键的权衡对我来说你是否要把一个活的生产体系有一个例外,以避免腐败和使故障排除更加容易,或者是否有遭遇的情况下,不应该允许继续被忽视,测试和调试版本,但可能允许其继续生产(记录的警告然)。

cf. http://c2.com/cgi/wiki?FailFast 复制和修改,从爪哇的问题: 异常Vs的断言

这里是2美分。

我认为,最好的办法就是使用这两种说法和例外情况。之间的主要区别两种方法,恕我直言,如果声称的语句可以删除的申请文本(定义,有条件的属性...),而引发的异常都依赖(tipically)通过有条件代码,这是难以消除(multine部分与预处理器的条件).

每个应用程序的例外,应正确处理,而主张应当满足于仅在算法开发和测试。

如果你通过一个空对象参考作为程序的参数和使用此价值的,你得到一个空的指针例外。事实上:为什么你应该编写一个说法?这是浪费时间在这种情况。但是,关于私人类成员使用的课程序?当这些价值是设置在某个地方,是更好地检查与一个断言,如果一个空值设定。那只是因为当你使用的部件,你会得到一个空指针异常,但你不知道如何价值。这会导致重新启动该程序打破在所有入境点使用设置私人部件。

例外是更多有用的,但他们可以(恕我直言)非常重要管理,并有可能使用太多的例外情况。他们需要额外的检查,也许不需要的最优化的代码。我个人使用例外的唯一当代码需要一个深刻赶上的控制(赶上发言是非常低的电话stack)或当的参数的功能不是硬编码代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top