Иногда я сталкиваюсь с методами, в которых разработчик решил вернуть что-то, что не критично для функции. Я имею в виду, что, глядя на код, он, очевидно, работает так же хорошо, как void
и, после некоторого момента я спрашиваю: «Почему?» Это звучит знакомо?
Иногда я соглашусь с тем, что чаще всего лучше вернуть что-то вроде bool
или int
, а не просто сделать void
. Я не уверен, хотя, в целом, о плюсах и минусах.
В зависимости от ситуации, возвращение int
может сообщить вызывающей стороне количество строк или объектов, на которые воздействует метод (например, 5 записей, сохраненных в MSSQL). Если такой метод, как «InsertSomething», возвращает логическое значение, я могу иметь метод, предназначенный для возврата в true
случае успеха, иначе false
. Абонент может выбрать, действовать или нет на эту информацию.
С другой стороны,
- Может ли это привести к менее ясной цели вызова метода? Плохое кодирование часто заставляет меня перепроверить содержание метода. Если он что-то возвращает, он говорит вам, что метод относится к типу, который вы должны сделать с возвращенным результатом.
- Другая проблема будет, если реализация метода вам неизвестна, что разработчик решил вернуть, который не является критически важным для функции? Конечно, вы можете это прокомментировать.
- Возвращаемое значение должно быть обработано, когда обработка может быть закончена на закрывающей скобке метода.
- Что происходит под капотом? Получил ли вызванный метод
false
из-за сгенерированной ошибки? Или он вернул false из-за оцененного результата?
Каков ваш опыт с этим? Как бы вы поступили с этим?
источник
void
по крайней мере, дает разработчику понять, что возвращаемое значение метода несущественно; он делает действие, а не вычисляет значение.Ответы:
В случае возвращаемого значения bool, указывающего на успех или неудачу метода, я предпочитаю
Try
парадигму -prefix, используемую в различных методах .NET.Например,
void InsertRow()
метод может вызвать исключение, если уже существует строка с таким же ключом. Вопрос в том, разумно ли предположить, что вызывающая сторона гарантирует, что их строка уникальна перед вызовом InsertRow? Если ответ отрицательный, то я бы также предоставил,bool TryInsertRow()
который возвращает false, если строка уже существует. В других случаях, таких как ошибки подключения к базе данных, TryInsertRow может по-прежнему выдавать исключение, предполагая, что поддержание подключения к базе данных является обязанностью вызывающей стороны.источник
ИМХО возвращение «кода состояния» происходит с исторических времен, до того, как исключения стали обычным явлением в языках среднего и более высокого уровня, таких как C #. В настоящее время лучше создать исключение, если какая-то непредвиденная ошибка помешала успешному выполнению вашего метода. Таким образом, эта ошибка не останется незамеченной, и вызывающая сторона может справиться с ней соответствующим образом. Таким образом, в этих случаях вполне нормально, чтобы метод ничего не возвращал (т.е.
void
) вместо логического флага состояния или целочисленного кода состояния. (Конечно, следует документировать, какие исключения метод может генерировать и когда.)С другой стороны, если это функция в строгом смысле, то есть она выполняет некоторые вычисления на основе входных параметров, и ожидается, что она вернет результат этих вычислений, тип возврата очевиден.
Между ними существует серая область, когда кто-то может решить вернуть некоторую «дополнительную» информацию из метода, если это считается полезным для его вызывающих. Как и ваш пример с количеством затронутых строк во вставке. Или для метода, чтобы поместить элемент в ассоциативную коллекцию, может быть полезно вернуть предыдущее значение, связанное с этим ключом, если оно было. Такое использование может быть идентифицировано путем тщательного анализа (известных и ожидаемых) сценариев использования API.
источник
Ответ Петра охватывает исключения хорошо. Другое соображение здесь включают Command-Query Separation
Принцип CQS гласит, что метод должен быть либо командой, либо запросом, а не обоими. Команды никогда не должны возвращать значение, только изменять состояние, а запросы должны только возвращать, а не изменять состояние. Это сохраняет семантику очень ясной и помогает сделать код более читабельным и понятным.
Есть несколько случаев нарушения принципа CQS, это хорошая идея. Обычно они связаны с производительностью или безопасностью потоков.
источник
Каким бы ни был путь, по которому вы идете. Не иметь возвращаемых значений для будущего использования (например, иметь функции, всегда возвращающие true), это ужасная трата усилий и не делает код более понятным для чтения. Когда у вас есть возвращаемое значение, вы всегда должны использовать его, и чтобы иметь возможность использовать его, у вас должно быть как минимум 2 возможных возвращаемых значения.
источник
Раньше я писал много пустых функций. Но так как я применил весь метод цепочки трещин, я начал возвращать это, а не пустоту - он мог бы также позволить кому-то воспользоваться возвратом, потому что вы не можете приседать с пустотой. И если они не хотят ничего с этим делать, они могут просто игнорировать это.
источник
Ruby
какой-то момент? Вот что познакомило меня с методом цепочки.return Thing.Change1().Change2();
ожидает ли оператор типа изменитьThing
и вернуть ссылку на оригинал, или же он должен будет возвращать ссылку на новую вещь, которая отличается от оригинала, оставляя при этом оригинальный нетронутый.