在这种情况下我应该使用例外吗?

时间:2009-11-26 08:14:44

标签: c# exception exception-handling

我设计了一个简单的程序,它有一个计数器类,在计数器类里面,我有一些方法可以增加计数,减少计数,等等。然后我向用户展示一个菜单,让他们输入他们的选择,例如。输入1作为选项1,等等。好吧,我不希望计数为负数,所以为了处理这个,我得到了计数器类的SubtractCount方法,当count<时,我会抛出一个ArguemetOutOfRangeException。 0.

然后我的switch语句捕获该异常(如果发生)。我的问题是:使用例外以确保计数永远不会是负数是不是很糟糕?我应该采用不同的方式吗?或者更好的是,有没有更好的方法来实现这一目标?

代码段:

static void Driver()
{
    switch (userChoice)
    {
        case 1: // if user picks a 1, the count is deincremented
            try {

                myObjectOfCounterClass.SubtractCount();
            }
            catch (ArguemetOutOfRangeException ex)
            {
                console.writeLine(ex.message);
            }
         break;
         // case 2, case 3 etc.
     }

class Counter
{
    private int count;

    public void SubtractCount()
    {
        if (count < 0)
            throw new ArguementOutOfRangeException("The count can never be negative!");
        else
            count--;
    } 

7 个答案:

答案 0 :(得分:7)

使用控制流的异常不被视为良好做法。在您的情况下,Tester-Doer模式会更合适。

您可以将您的Counter类更改为以下内容:

class Counter
{
    private int count;

    public bool CanSubtractCount
    {
        get { return this.count >= 0; }
    }

    public void SubtractCount()
    {
        if (!this.CanSubtractCount)
            throw new InvalidOperationException("The count can never be negative!");
        else
            this.count--;
    } 

您现在可以像这样重写您的客户:

static void Driver()
{
    switch (userChoice)
    {
        case 1: // if user picks a 1, the count is deincremented
            if(myObjectOfCounterClass.CanSubtractCount)
            {
                 myObjectOfCounterClass.SubtractCount();
            }
            else
            {
                 // Write a message to the user?
            }
         break;
         // case 2, case 3 etc.
     }
}

答案 1 :(得分:1)

异常处理可能会占用大量资源。如果你打算抛出异常以便捕获它并禁止它,那就不要这样做了。 而是做一些事情,比如从方法返回一个bool来表示调用者的成功。

public bool SubtractCount() { 
   if (count < 0)
        return false;
   count--;
   return true;
}

调用者仍然可以使用类似的逻辑来处理这种情况,但没有例外

if (!myObjectOfCounterClass.SubtractCount())
   Console.writeLine("The count cannot be negative");

这就是要点。

当您不想处理它们时,或者如果您无法处理它们,或者您希望将错误传播到您的直接编程上下文之外时抛出异常。使用异常处理等功能很有趣,但它们可能过头了 - 我常常对.NET框架中有趣的功能做同样的事情。

答案 2 :(得分:1)

当您可以使用流量控制时,不应该使用流量控制的异常。您可以检查小于零,并且(a)不对其采取行动或(b)显示消息或(c)在他们所在的位置关闭事物。

除了你之外,你基本上把所有东西放在地板上,好像发生了一场大灾难,它可以更优雅地处理,甚至发出警告并继续。

答案 3 :(得分:1)

如果值已经为零,我认为在SubtractCount()方法中抛出异常是可以的。

顺便说一句,if (count < 0)不应该是if (count == 0)

但是,我会让UI阻止用户选择减法计数,如果它已经为零,从而首先避免了例外情况。

顺便说一下 - 不要引发ArgumentOutOfRangeException。当传递给方法的参数不在可接受的范围内时,应该使用此方法。您的方法不接受任何参数。更合适的异常类型是InvalidOperationException。

答案 4 :(得分:0)

实际上,当计数&lt; 0不是“例外”。对此使用正常的“if”,不需要例外。

答案 5 :(得分:0)

嗯,首先你应该确保计数器实际上不能为负数。目前,如果你试图将它减少到-2,它将递减到-1并抛出异常。

作为仅捕获异常的替代方法,您可以将支票公开为CanDecrement属性,以便可以单独使用:

class Counter {

  private int count;

  public bool CanDecrement { get{ return count > 0; } }

  public void Decrement() {
    if (!CanDecrement) {
        throw new ArguementOutOfRangeException("The count can never be negative!");
    }
    count--;
  }

}

用法:

if (myObjectOfCounterClass.CanDecrement) {
  myObjectOfCounterClass.Decrement();
} else {
  Console.WriteLine("The count can not be negative.");
}

通过这种方式,您可以将该属性用于您希望条件发生的代码,并且在代码中通常不会发生这种情况,您只需调用Decrement并像处理任何其他意外错误一样处理异常。

答案 6 :(得分:0)

只有在特殊情况下才能使用异常,用户再次单击减少按钮并不例外,您可以通过简单的控制逻辑来处理它。你可以不减少计数器,如果它达到零,你应该改变你的用户界面,如果计数器达到零,它应该阻止用户减少选项,这样用户永远不会有选择进一步降低它。