Когда метод «Try» предпочтительнее, чем «нулевой» результат? - PullRequest
3 голосов
/ 08 февраля 2012

В .NET Framework (вокруг появления обобщений) появился шаблон Try[method], помогающий справиться с ситуацией, когда необходимо указать, что операция не завершилась успешно, без исключения.

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

Однако, если метод может вернуть null, чтобы указать, что он не смог получить значение успешно(например, в случае метода Find), считается ли это более правильным, чем метод TryFind, который четко указывает на успех или неудачу с возвращаемым значением?Есть ли какой-либо прецедент, установленный .NET Framework для этого шаблона?

Ответы [ 7 ]

2 голосов
/ 08 февраля 2012

Я полагаю, что шаблон TryX предшествует типам Nullable<T>, которые были добавлены в .NET 2.0. Nullable<T> решена проблема типов значений и потенциальных расхождений между тем, было ли значение типа по умолчанию действительным / недействительным. Тем не менее, даже с этими дополнениями, я уверен, что образец TryX по-прежнему имеет значение.

Два основных преимущества шаблона TryX:

  • Нет двусмысленности возвращаемого значения.
  • Безопасность от исключений.

Nullable<T> типы устраняют неоднозначность, но не обеспечивают исключительную безопасность.

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

2 голосов
/ 08 февраля 2012
  1. Нормальные типы значений не поддерживают null. И хотя существуют типы значений, допускающие значение NULL, универсальные элементы не поддерживают такую ​​конструкцию, как: Return T?, если T является типом значения, и T, если это ссылочный тип.
  2. Для типов, поддерживающих null, null является допустимым значением. Пользователи могут захотеть различать пропущенные записи и записи, которые null.

С другой стороны, можно определить структуру Option<T>, которая будет возвращена. Такой тип также будет полезен в других местах (например, необязательные параметры).


Интересно, что неуниверсальный класс HashTable возвращает null в своем индексаторе, когда элемент отсутствует:

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

Чтобы различать значение NULL, возвращаемое из-за того, что указанный ключ не найден, и значение NULL, возвращаемое из-за того, что значение указанного ключа равно NULL, используйте метод Contains или метод ContainsKey, чтобы определить, существует ли ключ в списке.

2 голосов
/ 08 февраля 2012

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

Использование метода типа Try* делает поток намного более четким.

Сказав это, шаблон нулевого объекта существует именно из-за проблем с возвратом нулевого - он позволяет вам использовать «нулевой» объект для вашего типа, действительный объект, который представляет нейтральное значение .

1 голос
/ 08 февраля 2012

Многие методы TryParse возвращают значения, а не объекты, что означает, что они не могут возвращать ноль.Конечно, с введением Nullable они могут быть написаны так, чтобы возвращать ноль, но ноль определяется как «нет информации».В случае исключения / ошибки это не семантически правильно.Возвращая истину при успехе и ложь при неудаче ясно представляют эту информацию.Как указано ниже, это также соответствует дизайну метода TryParse в .NET Framework.Они были введены одновременно с Nullable. Вы также избегаете использования возвращаемого значения без проверки на нулевое значение, что проще сделать по ошибке, чем забыть проверить результат метода TrySomthing

0 голосов
/ 08 февраля 2012

Для методов, возвращающих типы классов, я бы предпочел, чтобы метод TryGetFnord(), который возвращает ноль при ошибке, был предпочтительнее метода, который возвращает bool и сохраняет свой результат в параметре ref. Среди прочего, можно включить первый стиль в ковариантный интерфейс, тогда как нельзя сделать это с последним стилем. Однако я бы предложил оставить в названии слово «Попробуйте», чтобы указать, что метод может не сработать.

Другим подходом, который следует рассмотреть, будет что-то вроде: dataType TryGetFnord(ref TryGetFnordResult result), где TryGetFnordResult может быть типом значения или типом неизменяемого класса, который указывает, была ли операция выполнена успешно. Это сохранит преимущества, связанные с ковариацией, и позволит возвращать больше полезной информации, чем просто сбой. В случае сбоя операции она, вероятно, должна вернуть значение по умолчанию для своего типа, но вызывающая сторона должна проверить наличие ошибок, используя параметр result.

0 голосов
/ 08 февраля 2012

Одной из причин является то, что вы возвращаете структуру, которая не может быть null, т.е. double.TryParse().

0 голосов
/ 08 февраля 2012

исключения никогда не должны использоваться для контроля потока или результатов метода.Конечно, всегда есть исключения из этого правила.это одна из причин использования TryParse сверх Try

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