我设计了一个简单的程序,它有一个计数器类,在计数器类里面,我有一些方法可以增加计数,减少计数,等等。然后我向用户展示一个菜单,让他们输入他们的选择,例如。输入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--;
}
答案 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)
只有在特殊情况下才能使用异常,用户再次单击减少按钮并不例外,您可以通过简单的控制逻辑来处理它。你可以不减少计数器,如果它达到零,你应该改变你的用户界面,如果计数器达到零,它应该阻止用户减少选项,这样用户永远不会有选择进一步降低它。