Здравствуйте, Sinix, Вы писали:
S>Казалось бы, идеальный пример для local functions.
Не уверен. Идеальный пример для local functions — рекурсивные функции. Практически всегда сигнатура и предусловия вызова функции внешним клиентом отличается от самовызова функции в её реализации. Поэтому стабы рекурсивных функций типа такой
public long Fib(int n)
{
throw new NotImplementedException();
}
можно сразу переписать (на псевдокоде) как
public long Fib(int n)
{
local long FibRecursive(int n)
{
throw new NotImplementedException();
}
return FibRecursive(n);
}
Потом уже добавить при необходимости аккумулятор-состояние в сигнатуру внутренней функции, проверки на API boundaries во внешней функции, etc. Именно так устроены стандартные рекурсивные ФВП в библиотеках всяких ФЯПов типа Хаскеля.
И выносить подобное «ядро» функции в скоуп класса — совсем моветон. Не говоря уже о том, что в такого рода рекурсивных функциях часто очень удобно замкнуть некоторые входящие параметры (неизменные от вызова к вызову) и не загромождать сигнатуру локальной функции.
S>Не, фигня получается. В результате в одном методе смешиваются две ответственности: реализация и собственно логика в виде наборов вызовов этой самой реализации.
Всё равно что сказать: в одном методе смешивается инициализация локальной переменной и её использование.
S>Ну, т.е. мы вернулись к ситуации, от которой пытались уйти рефакторингом на отдельные методы
Не вернулись. Те же отдельные методы, только
инкапсулированы в скоупе. Никто же, надеюсь, не создаёт поля типа
private int _loopCounterForFooMethod;
private int _loopCounterForBarMethod;
private int _anotherLoopCounterForBarMethod;