Visual Studioでメソッドの抽出をしてみた
ソフトウェアの外から見た動作は変えないで中身のプログラムを整理することをリファクタリングと呼びます。Visual Studioのリファクタリングの機能の一つに、メソッドの抽出というものがあります。ちょっと試してみました。 以下の環境で試しました。
- Visual Studio 2015 Express for Windows Desktop (C#) 
目次
例えばこんな状況に
ツールを作っていて、作り始めてから「やっぱりこの機能を足そう!」とか「やっぱりボタンだけじゃなくてメニューからも同じ機能を呼び出せるようにしよう!」なんてことが(私は)よくあります。きちんと設計してから作り始めないからですね。
仮に、フォームにテキストボックス1つとボタンが2つあって、ボタンを押すとそれぞれに対応したテキストをテキストボックスに表示するアプリを作ると思ってください。
 そうすると、プログラムはこんな感じになります。
 そうすると、プログラムはこんな感じになります。
namespace refactoring_trial
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void buttonHoge_Click(object sender, RoutedEventArgs e)
        {
            textBox.Text = "ほげ";
        }
        private void buttonPiyo_Click(object sender, RoutedEventArgs e)
        {
            textBox.Text = "ぴよ";
        }
    }
}
ここで、「ボタンを押したら赤色で表示するようにしたいなあ」と思ったりします。そうすると、
textBox.Foreground = Brushes.Red;
を両方のボタンのクリックイベントに追記することになります。この程度の処理ならコピペの方が早いのですが、もしもっと複雑な処理が必要な場合、コピペで両方のイベントに同じコードを追記すると、後で何か修正や変更が必要になったときに変更漏れが起きたりします。ということで、この処理をメソッドにして、各イベントからメソッドを呼び出すようにします。
メソッドを抽出してみた
まず、メソッドにするコードを選択します。そして、メニューの「編集」→「リファクター」→「メソッドの抽出」を選びます。
 そうすると、「NewMethod」という名前でメソッドが作られます。
そうすると、「NewMethod」という名前でメソッドが作られます。
 そのまま新しいメソッドの名前をタイプして「適用」をクリックすると、メソッドの抽出が終わります。
そのまま新しいメソッドの名前をタイプして「適用」をクリックすると、メソッドの抽出が終わります。

メソッドを抽出するときに引数も考慮してくれます
たとえば、次のようなコードをメソッドに抽出するとします。
private void buttonHoge_Click(object sender, RoutedEventArgs e)
{
    string str = "ほげ";
    // ここから
    textBox.Foreground = Brushes.Red;
    textBox.Text = str;
    // ここまで抽出する
}
そうすると、下記のように引数付きのメソッドにしてくれます。何気に便利かも。
private void buttonHoge_Click(object sender, RoutedEventArgs e)
{
    string str = "ほげ";
    FillFieldText(str);
}
private void FillFieldText(string str)
{
    textBox.Foreground = Brushes.Red;
    textBox.Text = str;
}
コード全体は下記のようになります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace refactoring_trial
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void buttonHoge_Click(object sender, RoutedEventArgs e)
        {
            string str = "ほげ";
            FillTextField(str);
        }
        private void FillTextField(string str)
        {
            textBox.Foreground = Brushes.Red;
            textBox.Text = str;
        }
        private void buttonPiyo_Click(object sender, RoutedEventArgs e)
        {
            string str = "ぴよ";
            FillTextField(str);
        }
    }
}
これで、各ボタンを押したときの共通の処理に変更が生じた場合は抽出したメソッドだけを変更すればよくなります。
まとめ
MSDNのヘルプを見るとVisual Studio 2010のヘルプにも記載があるので、けっこう古くからある機能のようですね。Visual Basicしてた頃はまったく気付かず、ちまちまサブルーチンにしてたりしました。
公開日
広告