Выдавание исключения к потоку управления - кодирует запах?

Изучив поведение атрибута checked для переключателя , я обнаружил, что ваша проблема возникла, потому что атрибут checked является логическим свойством, которое, когда атрибут присутствует, указывает, что соответствующий элемент ввода находится в проверенном состоянии независимо от того, его значения (checked="false" совпадает с checked="true" или checked="checked").

Если атрибут checked присутствует для нескольких переключателей в одной и той же группе, по умолчанию он устанавливает для последнего переключателя значение checked (см. эту скрипку на основе вашего исходного кода). Следовательно, вам нужно исключить атрибут checked, когда для свойства CompanionReleaseRadio1.Checked установлено значение false, используя вспомогательный метод встроенной функции @functions, как показано в примере ниже:

@functions {
    private object SetRadioButtonChecked(bool isChecked, string RadioID) 
    {
        // checked state from property
        if (isChecked)
        {
            // checked attribute is present
            return new { id = "CompanionReleaseRadio2" + RadioID, @checked = "checked" };
        }
        else
        {
            // checked attribute is not present
            return new { id = "CompanionReleaseRadio2" + RadioID };
        }
    }
}

Затем вызовите эту встроенную функцию выше внутри RadioButton ] помощник, подобный этому:

@foreach (var companionReleases1 in Model.CompanionReleaseRadios1)
{
    
@Html.RadioButtonFor(model => Model.CompanionReleaseRadio1, companionReleases1.RadioID, @SetRadioButtonChecked(companionReleases1.Checked, companionReleases1.RadioID)) @companionReleases1.RadioText
}

После этого все переключатели со свойством CompanionReleaseRadio1.Checked, установленным в false, должны были быть установлены в непроверенное состояние (см. эту скрипку для намеченного результата) .

Ссылка:

Использование @functions на странице ASP.NET с синтаксисом Razor

Проблемы, связанные с данной:

Как создать функцию в шаблоне cshtml?

asp.net mvc3 проверка переключателя на основе модели

6
задан Yuval Adam 17 September 2012 в 14:20
поделиться

15 ответов

Это полностью зависит от того, что то состояние ошибки, и каково задание метода. При возврате ERROR допустимый способ обработать ту ошибку для функции вызова, почему это было бы плохо?

Часто, однако, это - запах. Рассмотрите это:

bool isDouble(string someString) {
    try {
        double d = Convert.ParseInt32(someString);
    } catch(FormatException e) {
        return false;
    }
    return true;
}

Это - очень большой запах кода, потому что Вы не ожидаете двойное значение. Вы просто хотите знать, содержит ли строка двойное.

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

bool isDouble(string someString) {
    bool success;
    Convert.TryParseInt32(someString, ref success);
    return success;
}

Такие исключения имеют специальное имя, выдуманное некоторым чуваком, блог которого я недавно считал. Но к сожалению, я забыл его имя. Прокомментируйте, знаете ли Вы это. Наконец, что не менее важно, вышеупомянутое является псевдо кодом. Я не c# разработчик, таким образом, вышеупомянутое не компилирует, я уверен, но TryParseInt32 / ParseInt32 демонстрирует, что хорошо я думаю, таким образом, я иду с C#.

Теперь, к Вашему коду. Давайте осмотрим две функции. Каждый пахнет, и другой не делает:

1. Запах

public int setupSystem() {
    doA();

    try { doB(); }
    catch (MyException e)
    { return ERROR; } 

    doC();
    return SUCCESS;
}

Это - запах кода, потому что, когда Вы хотите установить систему, Вы не хотите, чтобы она перестала работать. Отказ установить систему означает, что Вы не можете продолжить, не обрабатывая ту ошибку.

2. Хорошо

public int pingWorkstation() {
    doA();

    try { doB(); }
    catch (MyException e)
    { return ERROR; } 

    doC();
    return SUCCESS;
}

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

11
ответ дан 8 December 2019 в 02:04
поделиться

Вы парни уничтожаете меня здесь. Вы НИКОГДА не хотите использовать исключения для потока управления. Это очень не отличалось бы, чем использование goto statments везде!

Исключениями является исключение, означая что-то, что ООН ожидала, произошел. Что-то так, таким образом, мы останавливаем выполнение приложения. Любой, кто работал над приложением, был этим типом управления потоком исключения, испекся в, захочет выследить разработчика, который сделал это и регулирует его (или ее).

Используя исключение, поскольку управление потоком делает maintainence и разработку новой возможности кошмаром!

-2
ответ дан 8 December 2019 в 02:04
поделиться

Вот то, как я обработал бы его:

public void doSomething() 
        throws MyException{
    doA();

    try { 
        doB();
    } finally {
        doC();
    }
}

Если ошибка произойдет на д.р. (), то исключение распространит стек.

-1
ответ дан 8 December 2019 в 02:04
поделиться

В C# выдавание исключения является относительно дорогим, мудрым производительностью – таким образом другая причина избежать их использования для управления потоком. Имеет место это в Java? Да, существует аргумент, который будет сделан для того, чтобы не сверхпроанализировать производительность заранее. Но если Вы знаете, что что-то займет дополнительное время и его легкое для предотвращения, разве Вы не должны делать этого? Если Вы действительно не заботитесь!

0
ответ дан 8 December 2019 в 02:04
поделиться

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

0
ответ дан 8 December 2019 в 02:04
поделиться

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

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

То, что код Вы возвращаетесь когда doB() выдает исключение, назван ERROR, Тем не менее, указывает, что это - вероятно, отказ, который предотвратил бы любую операцию doSomething() часть от завершения. В этом случае Вы не должны, вероятно, ловить исключение, выданное doB() и просто позвольте ему быть подброшенным стек, пока это не достигает точки, где это может быть обработано или пока это не достигает Вашего общего обработчика ошибок, который может сообщать/регистрировать об этом или что бы то ни было.

0
ответ дан 8 December 2019 в 02:04
поделиться

В зависимости от логики д.р. у Вас могли быть некоторые возвращаемые значения, указывающие, была ли она в порядке или нет, и затем doSomething мог бы использовать возвращенное значение для обработки ситуации соответствующим способом.

1
ответ дан 8 December 2019 в 02:04
поделиться

Исключения для нестандартного поведения. Так да нормально использовать их для управления потоком.

Как Sun выражается:

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

Вот инструкция по нижней строке: Если клиент, как могут обоснованно ожидать, восстановится с исключения, сделайте его контролируемой исключительной ситуацией. Если клиент не может сделать ничего для восстановления с исключения, сделайте его исключением непроверенным.

Просто не забудьте не разделять на подклассы RuntimeException, но Исключение, поскольку это быстрее.

1
ответ дан 8 December 2019 в 02:04
поделиться

Нормально выдавать Исключение в случае ошибки, как на д.р. (). Но проблемой является функция doSomething ().

Вы не должны использовать операторы возврата для indicete успешности или неуспешности. Необходимо сделать:

try { 
    doB();
} catch (MyException e) {
    throw MyException2(e);
}
2
ответ дан 8 December 2019 в 02:04
поделиться

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

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

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

Как пример того, какой не сделать, это использовало бы исключения для управления потоком:

public int calculateArraySize(Object[] array)
{
   int i = 0;
   try
   {
      array[i++];
   }
   catch (ArrayIndexOutOfBoundsException ignore) {}
   return i;
}

Я полагаю, что это возвратит правильный результат, но это будет ужасно медленно и неэффективно, а также трудно читать для людей, которые привыкли к исключениям, используемым правильно.;-)

С другой стороны, что-то вроде этого было бы в порядке, по-моему:

public void myMethod(int count, Foobar foo) throws MyPackageException
{
   validateArgs(count, foo);

   // Stuff
}

private void validateArgs(int count, Foobar foo) throws MyPackageException
{
   if (m_isClosed)
   {
      throw new IllegalStateException("Cannot call methods on a closed widget");
   }

   if (count < 0)
   {
      throw new IllegalArgumentException("count must be greater than zero");
   }

   foo.normalise(); // throws MyPackageException if foo is not fully initialised at this point
}

Несмотря на то, что весь второй метод делает, потенциально выдают исключение, он не делает этого для управления процессом выполнения программы, но повышает их в ответ на исключительные условия.

4
ответ дан 8 December 2019 в 02:04
поделиться

Исключения должны использоваться когда:

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

Помните, прежде всего, что исключениями, как возвращаемые значения или параметры метода, являются просто сообщения, отправленные между различными частями кода. Стремитесь оптимизировать баланс между информацией, переданной с помощью этих методов и простотой API. Когда простой флаг SUCCESS/FAILURE - все, в чем это нуждалось (и метод не должен возвращать другие значения), используйте это. Если метод уже должен возвратить значение, обычно необходимо использовать исключение (который является, к одному способу посмотреть на него, просто "исключительное" возвращаемое значение из метода). Если информация об отказах, которая должна быть передана, слишком богата, чтобы быть переданной в возвращаемом значении (например, причина отказа ввода-вывода), используйте исключение.

Наконец, обработка ошибок является проектным решением, и нет никакого единого подшипника, который покроет все случаи.

5
ответ дан 8 December 2019 в 02:04
поделиться

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

Править: В Вашем комментарии Вы описали точно scenarion, где необходимо просто объявить

public void doSomething() throws MyException
16
ответ дан 8 December 2019 в 02:04
поделиться

Моя единственная проблема с кодом OP состоит в том, что Вы смешиваете парадигмы - д.р. показывает ошибку путем выдачи исключения, в то время как doSomething показывает ошибку путем возврата кода. Идеально, Вы выбрали бы один или другой. Конечно, в обслуживании прежней версии, у Вас не могло бы быть той роскоши.

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

9
ответ дан 8 December 2019 в 02:04
поделиться

Мне никогда не нравилось использовать исключения для потока управления (на некоторых языках, как CLR, они являются дорогими).

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

public int doSomething()
{
    doA();

    if (!doB()) {
        return ERROR;
    }

    doC();
    return SUCCESS;
}
6
ответ дан 8 December 2019 в 02:04
поделиться

Исключения не должны использоваться только для контроля потока. Проверенные исключения должны использоваться, чтобы сообщить вызывающему коду, что определенные условия контракта API не были выполнены. Я бы не стал проектировать doSomething для обработки случаев, когда вызовы doB будут часто терпеть неудачу, используя блок try/catch. Если вам нужно справиться с частыми неудачами, я бы разработал doB, возвращающий успех или неудачу boolean, чтобы указать вызывающим его методам, следует ли продолжать работу с их собственными методами типа doC-

public int doSomething() {
    doA();

    if ( doB() )
       doC();
       return SUCCESS;
    } else { 
       return ERROR; 
    }
}    
2
ответ дан 8 December 2019 в 02:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: