Должен ли я использовать исключение в этом случае? - PullRequest
2 голосов
/ 26 ноября 2009

Я разработал простую программу, у которой есть класс счетчика, и внутри этого класса счетчика у меня есть методы, которые увеличивают счет, деинкрементируют счет и так далее. Затем я представляю меню пользователю и заставляю его вводить выбор, напр. введите 1 для первого варианта и т. д. Ну, я никогда не хочу, чтобы число было отрицательным, поэтому для обработки этого у меня был метод SubtractCount класса counter, который генерировал исключение ArguemetOutOfRangeException, когда count <0. </p>

Затем мой оператор 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 ]

7 голосов
/ 26 ноября 2009

Использование исключений для потока управления не считается хорошей практикой. В вашем случае лучше подойдет шаблон 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 голос
/ 26 ноября 2009

Я думаю, что это нормально, чтобы генерировать исключение в методе SubtractCount (), если значение уже равно нулю.

Кстати if (count < 0) не должно быть if (count == 0)?

Однако я бы сделал так, чтобы пользовательский интерфейс не позволял пользователю выбирать счетчик вычитания, если он уже равен нулю, что исключает в первую очередь исключительную ситуацию.

Кстати - не вызывать ArgumentOutOfRangeException. Это следует использовать, когда аргумент, переданный методу, находится вне допустимого диапазона. Ваш метод не принимает никаких аргументов. Более подходящим типом исключения будет InvalidOperationException.

1 голос
/ 26 ноября 2009

Вы не должны использовать исключения для управления потоком, когда вы можете просто использовать управление потоком. Вы можете проверить на наличие меньше нуля и либо (а) не действовать на него или (б) показать сообщение или (в) закрыть вещи прямо там, где они находятся.

За исключением того, что вы в основном бросаете все на пол, как если бы произошла великая катастрофа, когда с ней можно справиться намного более изящно, и даже дать предупреждение и продолжить.

1 голос
/ 26 ноября 2009

Обработка исключений может быть ресурсоемкой. Если вы планируете бросить исключение, чтобы поймать его и подавить, не делайте этого. Вместо этого сделайте что-то вроде возврата bool из метода, чтобы указать вызывающему абоненту на успех.

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

Абонент все еще может справиться с ситуацией с подобной логикой, но без исключений

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

Это суть.

Бросайте исключения, когда вы не хотите обрабатывать их, или если вы не можете их обработать или хотите, чтобы ошибка распространялась вне вашего непосредственного контекста программирования. Забавно использовать такие функции, как обработка исключений, но они могут перестараться - я часто виновен в том, что делаю то же самое с интересными функциями в .NET Framework.

0 голосов
/ 26 ноября 2009

Исключения следует использовать только в исключительных обстоятельствах, пользователь, нажимающий еще раз на кнопку уменьшения, не является исключением, вы можете справиться с ним с помощью простой логики управления. Вы можете просто не уменьшать счетчик, если он достиг нуля, кроме того, вы должны изменить свой пользовательский интерфейс, он должен заблокировать опцию уменьшения для пользователя, если счетчик достиг нуля, поэтому у пользователя никогда не будет возможности уменьшить его дальше.

0 голосов
/ 26 ноября 2009

Ну, во-первых, вы должны убедиться, что счетчик на самом деле не может быть отрицательным. В настоящее время он уменьшится до -1 и выдаст исключение, если вы попытаетесь уменьшить его до -2.

В качестве альтернативы простому перехвату исключения вы можете выставить чек как свойство 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 и разрешить обработку исключения, как любую другую непредвиденную ошибку.

0 голосов
/ 26 ноября 2009

На самом деле, похоже, что ситуация, когда count <0, не является "исключительной". Используйте для этого обычное «если», исключение не требуется. </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...