Рефакторинг для извлечения метода (C#)
Извлечение метода — это операция рефакторинга, обеспечивающая простой способ создания нового метода из фрагмента кода существующего члена.
С помощью операции Извлечение метода можно создать новый метод путем извлечения выделенного кода, находящегося внутри блока кода существующего члена.Новый, извлеченный метод содержит выделенный код, а выделенный код в существующем члене меняется на вызов нового метода.Превращение фрагмента кода в отдельный метод позволяет быстро и точно реорганизовать код с целью его много кратного использования и лучшей читаемости.
Операция Извлечение метода позволяет получить следующие преимущества:
Способствует использованию лучших методов программирования, выделяя отдельные, многократно используемые методы.
Способствует получению самодокументирующего кода за счет хорошей организации.
При использовании описательных имен методы верхнего уровня можно читать как последовательности комментариев.
Способствует созданию сильно детализированных методов для упрощения переопределения.
Сокращает дублирование кода.
Чтобы воспользоваться операцией "извлечение метода"
Создайте консольное приложение с именем ExtractMethodи затем замените Program следующим примером кода.
class A { const double PI = 3.141592; double CalculatePaintNeeded(double paintPerUnit, double radius) { // Select any of the following: // 1. The entire next line of code. // 2. The right-hand side of the next line of code. // 3. Just "PI *" of the right-hand side of the next line // of code (to see the prompt for selection expansion). // 4. All code within the method body. // ...Then invoke Extract Method. double area = PI * radius * radius; return area / paintPerUnit; } }
Выберите фрагмент кода, которые нужно извлечь:
double area = PI * radius * radius;
В меню Оптимизация выберите пункт Извлечение метода.
Откроется диалоговое окно Извлечение метода.
В качестве альтернативы, диалоговое окно Извлечение метода можно открыть нажатием на клавиатуре сочетания клавиш CTRL+R, M.
Кроме того, можно щелкнуть правой кнопкой мыши выделенный код, навести курсор на пункт меню Оптимизация и затем выбрать пункт Извлечение метода, после чего откроется диалоговое окно Извлечение метода.
Укажите имя нового метода, например CircleArea, в поле Имя нового метода.
Предварительный просмотр сигнатуры нового метода отображается в области Предварительный просмотр сигнатуры метода.
Нажмите кнопку ОК.
Заметки
При использовании команды Извлечение метода новый метод вставляется после исходного члена в тот же класс.
Разделяемые типы
Если класс является разделяемым типом, то операция Извлечение метода приводит к генерированию нового метода непосредственно после исходного члена.Операция Извлечение метода определяет сигнатуру нового метода, создавая статический метод, если в коде нового метода нет ссылок на данные экземпляра.
Параметры универсального типа
При извлечении метода, имеющего неограниченный параметр универсального типа, в сгенерированном коде модификатор ref к этому параметру не добавляется, если ему не присваивается значение.Если извлеченный метод будет поддерживать ссылочные типы в качестве аргумента универсального типа, то необходимо вручную добавить модификатор ref к параметру сигнатуры метода.
Анонимные методы
При попытке извлечь часть анонимного метода, включающего ссылку на локальную переменную, которая объявлена или ссылка на которую существует за пределами анонимного метода, среда разработки Visual Studio выдаст предупреждение о возможных изменениях семантики.
Если анонимным методом используется значение локальной переменной, то это значение получается в момент выполнения анонимного метода.При извлечении анонимного метода в другой метод значение локальной переменной получается в момент вызова извлеченного метода.
Следующий пример демонстрирует это изменение семантики.В случае выполнения этого кода на консоль будут выведены символы 11.При использовании операции Извлечение метода с целью извлечения отмеченного комментариями региона кода в отдельный метод и последующем выполнении полученного в результате оптимизации кода на консоль будут выведены символы 10.
class Program
{
delegate void D();
D d;
static void Main(string[] args)
{
Program p = new Program();
int i = 10;
/*begin extraction*/
p.d = delegate { Console.WriteLine(i++); };
/*end extraction*/
i++;
p.d();
}
}
Чтобы обойти эту ситуацию, сделайте локальные переменные, используемые в анонимном методе, полями класса.