Есть ли название для этого "шаблона"?

Мне интересно, есть ли имя для этого "шаблона", где подпись метода называется TrySomething, например. int.TryParse, decimal.TryParse и т.д.

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

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

Изменить: Интересный...

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

Чтобы реализовать шаблон TryParse, вы предоставляете два разных метода для выполнения операции, которая может генерировать исключения в общих сценариях. Первый метод, X, выполняет операцию и выдает исключение, когда это необходимо. Второй метод TryX не генерирует исключение, но вместо этого возвращает логическое значение, указывающее на успех или неудачу. Любые данные, возвращаемые успешным вызовом TryX, возвращаются с использованием параметра out (ByRef in Visual Basic). Способы Parse и TryParse являются примерами этого шаблона.

Ответ 1

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

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

В принципе, если априори вы знаете, что операция завершится с ошибкой, логично и правильно обеспечить операцию компаньона TryX. Это так называемый шаблон Tester-Doer. Post hoc-анализ операции не Tester-Doer, а просто простая Обработка исключений.

Ответ 3

Прежде всего, если ваше описание является точным, это не то, как int.TryParse и его братья и сестры работают вообще.

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

На самом деле, лучший способ, на мой взгляд, был тем, что я видел в сторонней библиотеке, которую я не помню, но в основном у них были разные пользовательские типы, которые имели такую ​​пару методов Parse/TryParse и они сделали следующее:

  • Определите общую структуру, содержащую как значение, полученное путем синтаксического анализа строки, так и значение типа перечисления, передающего результат разбора
  • Все методы TryParse вернули эту структуру и не имели параметра out
  • Методы анализа просто называются методами TryParse, а затем переводили различные неудачные результаты этого перечисления в соответствующие исключения

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

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

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

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

Я бы серьезно посмотрел на ваш шаблон и попытался изменить его.

Конечно, все это зависит от того, что ваше описание точно.

Ответ 4

Я называю это "Желаем, чтобы у меня был Option<T>" Pattern (который похож на "Wish я have Either<T,E>" Pattern - представьте, где E: Исключение).

TryXYZ (в приведенных выше примерах) моделирует вариант с использованием логического результата и параметра out. (Для типов значений это может быть Nullable<T> в этом случае - я подозреваю, что это не так для int.TryParse и для друзей частично, потому что Nullable появился намного позже .NET). Возвращение исключения через out более похоже на Либо.

В С# я бы не рекомендовал исключать исключения только для того, чтобы передать их параметрам out в целом, хотя (это "правило" может отличаться от языка, который поддерживает распознанные объединения и сопоставление шаблонов) - я пытаюсь сделать 1 ) обрабатывают его "правильно", однако это определено, что очень хорошо может быть out в конкретных обстоятельствах; или 2) отпустите его, чтобы вызывающий мог попробовать то же самое.

(Как указывали другие, это скорее соглашение).

Счастливое кодирование.

Ответ 5

Вы можете назвать это ExceptionSafeBridge. Это приводит вас из мира исключений в мир ошибок. Но я не считаю это официальным.

Этот шаблон является общим, когда вам нужно переходить между, например, C и управляемый код.

Ответ 6

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

Ответ 7

Угу. Он назвал шаблон Tester-Doer.

Ответ 8

если проблема возникает во время tryparse i.e.

 int val;
        if(int.TryParse("2", out val))
        {
            //do work with val
        }

Тогда у вас не было бы исключения, пойманного через out param, значение 0 для out, false возвращаемое как логическое значение.

Лучше всего использовать "is" или "as" вместо этого.

На самом деле я бы не назвал подход, который вы описываете шаблон, хотя... Просто практика кодирования (не самая лучшая).

Пример as:

private void SetObj(object obj)
{
    int thisInt = obj as int;
    if(thisInt != null)
    {
       //do work
    }
    else
    {
       //handle issue
    }

}

Вышеупомянутое намного эффективнее во время выполнения, чем try/catch.

Если вы используете "is", когда недоступно для вас ( "как" не используется для всех типов), не забудьте добавить избыточность, реализуя, поскольку WITH... использует только тот или иной.