Для этого есть по крайней мере две причины:
1. Облегчение отладки - на возвращённые значения можно взглянуть до того, как они будут "похоронены" в сложных структурах данных или вообще исчезнут после сравнение (как в следующем примере: if (myVar == GetSomething())).
2. Если функция должна вызываться внутри сложного выражения, описываемый метод помогает разбить одну сложную строку на несколько простых.
Эти причины заставляют сохранять возвращённое значение всегда - даже если функция вызывается лишь один раз (если больше, тогда тем более нет вопросов). Единственное исключение из правила - логическая функция (т.е. возвращающая Boolean), которая вызывается в методе один раз и используется напрямую в выражении "if": в этом случае мы можем понять что вернулось (true or false) по тому, произошёл ли заход в "if" или программа "перескочила" через него (зайдя в "else" или пойдя дальше). Но в этом случае надо быть уверенным, что функция не вернёт null, который в данной ситуации интерпретируется как false).
Если вызываемая функция - детерминистическая (т.е. возвращает то-же значение в данном контексте) и должна быть вызвана в методе несколько раз, то у помещения возвращённого значения в переменную есть дополнительные преимущества:
1. Улучшение производительности (вызывается лишь раз), особенно если функция не особенно быстрая (например, идёт в базу данных).
2. Читающие код увидят, что функция - детерминистическая (иначе они могут подумать, что она возвращает разные значение при каждом вызове).
Этот совет особенно важен когда результат функции служит условием выхода из цикла Например:
Код: Выделить всё
for (i = 1; i++; i < this.FuckingSlowMethod())
{
...
}
Если метод возвращает 10000 то это значит, что столько раз он вызывается! Решение вам хорошо известно:
Код: Выделить всё
int cnt = this.FuckingSlowMethod();
for (i = 1; i++; i < cnt)
{
...
}
Но будьте осторожны - если цикл меняет что-то, что может повлиять на OUTPUT этого метода, он - не детерминистический!
Ещё один пример, показывающий преимущества обсуждаемого подхода (одна сложная строка разбивается на несколько простых - в принципе та-же философия, что и в рефакторинге методов):
*** Не рекомендуется: ***
Код: Выделить всё
countryName = this.GetCountryNameByCountryId(this.GetCountryIdByCityId(this.GetCityId(rowNum)));
*** Рекомендуется: ***
Код: Выделить всё
cityId = this.GetCityId(rowNum);
countryId = this.GetCountryIdByCityId(cityId);
countryName = this.GetCountryNameByCountryId(countryId);
Как видите, если переменная countryName в результате не была заполнена как ожидалось, то мы можем легко увидеть в дебаггере (без нескольких STEP IN / STEP OUT) какая именно из функций не справилась со своей задачей.