C#のリファクタリングとは?サンプルコードを用いて解説!

エンジニア
マネージャー
リファクタリングとは?
C#のリファクタリングについて説明いたします。
まずリファクタリングとは、プログラムを整理することです。同じ作業を繰り返している処理や、実は不要な処理などを修正、変更しプログラムを読みやすくすることです。
C#のリファクタリングに興味がある方はご覧ください。
C#でリファクタリングを行う方法
実際にプログラムをリファクタリングしてみます。
リファクタリングを行うプログラムを見てみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
using System; class Program_1 { static void Main(string[] args) { //文字合わせプログラム用 string Astr; string Bstr; string Cstr; //計算プログラム用 int Anum; int Bnum; int Cnum; int Dnum; //文字合わせプログラム起動フラグ string ToolFlgSTR; //計算プログラム Console.WriteLine("----------計算プログラム----------"); Console.WriteLine("このプログラムでは入力した3つの数字(A、B、C)に、1-10の値を掛けて表示します。"); //リファクタリング対処_1 Start Console.Write("\r\n" + "Aの値を入力してください:"); //コンソールからの数値入力_Anum Anum = int.Parse(Console.ReadLine()); Console.WriteLine("Aの値に1-10を掛けた値"); //1-10を掛ける処理_Anum for (int a = 1; a <= 10; a++) { if (a < 10) { Console.Write(Anum * a + "、"); } else { Console.WriteLine(Anum * a); } } Console.Write("\r\n" + "Bの値を入力してください:"); //コンソールからの数値入力_Bnum Bnum = int.Parse(Console.ReadLine()); Console.WriteLine("Bの値に1-10を掛けた値"); //1-10を掛ける処理_Bnum for (int b = 1; b <= 10; b++) { if (b < 10) { Console.Write(Bnum * b + "、"); } else { Console.WriteLine(Bnum * b); } } Console.Write("\r\n" + "Cの値を入力してください:"); //コンソールからの数値入力_Cnum Cnum = int.Parse(Console.ReadLine()); Console.WriteLine("Cの値に1-10を掛けた値"); //1-10を掛ける処理_Cnum for (int c = 1; c <= 10; c++) { if (c < 10) { Console.Write(Cnum * c + "、"); } else { Console.WriteLine(Cnum * c); } } //リファクタリング対象_1 End //リファクタリング対象_2 Start Dnum = 100; for (int d = 1; d >= 10; d++) { if (d < 10) { Console.Write(Dnum * d + "、"); } else { Console.WriteLine(Dnum * d); } } //リファクタリング対象_2 End Console.WriteLine("\r\n" + "計算が完了しました。"); Console.WriteLine("----------計算プログラム終了----------"); Console.Write("\r\n" + "続いて文字合わせプログラムを起動しますか?(Y/N):"); ToolFlgSTR = Console.ReadLine(); if (ToolFlgSTR == "Y") { Console.Write("\r\n"); } else { Console.WriteLine("プログラムを終了します。"); Environment.Exit(0); } //リファクタリング対象_3 Start //文字合わせプログラム Console.WriteLine("----------文字合わせプログラム----------"); Console.WriteLine("このプログラムでは入力した3つの文字(A、B、C)を、合わせて表示します。"); //コンソールからの値入力_Astr Console.Write("\r\n" + "Aの文字を入力してください:"); Astr = Console.ReadLine(); //コンソールからの値入力_Bstr Console.Write("\r\n" + "Bの文字を入力してください:"); Bstr = Console.ReadLine(); //コンソールからの値入力_Cstr Console.Write("\r\n" + "Cの文字を入力してください:"); Cstr = Console.ReadLine(); //結果表示 Console.WriteLine("\r\n" + "A、B、Cを合わせた値"); Console.WriteLine(Astr + Bstr + Cstr); Console.WriteLine("\r\n" + "合わせ終わりました。"); Console.WriteLine("----------文字合わせプログラム終了----------"); //リファクタリング対象_3 End } } |
実行結果:
———-計算プログラム———-
このプログラムでは入力した3つの数字(A、B、C)に、1-10の値を掛けて表示します。
Aの値を入力してください:10
Aの値に1-10を掛けた値
10、20、30、40、50、60、70、80、90、100
Bの値を入力してください:20
Bの値に1-10を掛けた値
20、40、60、80、100、120、140、160、180、200
Cの値を入力してください:30
Cの値に1-10を掛けた値
30、60、90、120、150、180、210、240、270、300
計算が完了しました。
———-計算プログラム終了———-
続いて文字合わせプログラムを起動しますか?(Y/N):Y
———-文字合わせプログラム———-
このプログラムでは入力した3つの文字(A、B、C)を、合わせて表示します。
Aの文字を入力してください:明日は
Bの文字を入力してください:晴れ
Cの文字を入力してください:ますか?
A、B、Cを合わせた値
明日は晴れますか?<
合わせ終わりました。
———-文字合わせプログラム終了———-
上記コード内にリファクタリング対象_X start/endと記述されています。そこをリファクタリング対象とします。
同じような処理
リファクタリング対処_1では、同じような処理を複数回行っています。今回の場合は処理を関数にすることができます。関数にすることで処理を一か所にし、呼び出すだけで使用できるようになります。
実際にC#でリファクタリングを行ってみます。
リファクタリング前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
using System; class Program_1 { static void Main(string[] args) { ------------- 同じ処理なので割愛 ------------- //リファクタリング対処_1 Start Console.Write("\r\n" + "Aの値を入力してください:"); //コンソールからの数値入力_Anum Anum = int.Parse(Console.ReadLine()); Console.WriteLine("Aの値に1-10を掛けた値"); //1-10を掛ける処理_Anum for (int a = 1; a <= 10; a++) { if (a < 10) { Console.Write(Anum * a + "、"); } else { Console.WriteLine(Anum * a); } } Console.Write("\r\n" + "Bの値を入力してください:"); //コンソールからの数値入力_Bnum Bnum = int.Parse(Console.ReadLine()); Console.WriteLine("Bの値に1-10を掛けた値"); //1-10を掛ける処理_Bnum for (int b = 1; b <= 10; b++) { if (b < 10) { Console.Write(Bnum * b + "、"); } else { Console.WriteLine(Bnum * b); } } Console.Write("\r\n" + "Cの値を入力してください:"); //コンソールからの数値入力_Cnum Cnum = int.Parse(Console.ReadLine()); Console.WriteLine("Cの値に1-10を掛けた値"); //1-10を掛ける処理_Cnum for (int c = 1; c <= 10; c++) { if (c < 10) { Console.Write(Cnum * c + "、"); } else { Console.WriteLine(Cnum * c); } } //リファクタリング対象_1 End ------------- 同じ処理なので割愛 ------------- } } |
リファクタリング後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
class Program_1 { static void Main(string[] args) { ------------- 同じ処理なので割愛 ------------- //リファクタリング対処_1 Start Console.Write("\r\n" + "Aの値を入力してください:"); //コンソールからの数値入力_Anum Anum = int.Parse(Console.ReadLine()); Console.WriteLine("Aの値に1-10を掛けた値"); //AnumをLoopXに渡し処理をする LoopX(Anum); Console.Write("\r\n" + "Bの値を入力してください:"); //コンソールからの数値入力_Bnum Bnum = int.Parse(Console.ReadLine()); Console.WriteLine("Bの値に1-10を掛けた値"); //BnumをLoopXに渡し処理をする LoopX(Bnum); Console.Write("\r\n" + "Cの値を入力してください:"); //コンソールからの数値入力_Cnum Cnum = int.Parse(Console.ReadLine()); Console.WriteLine("Cの値に1-10を掛けた値"); //BnumをLoopXに渡し処理をする LoopX(Cnum); //リファクタリング対象_1 End ------------- 同じ処理なので割愛 ------------- } static void LoopX(int CRnum) { //1-10を掛ける処理_CRnum for (int i = 1; i <= 10; i++) { if (i < 10) { Console.Write(CRnum * i + "、"); } else { Console.WriteLine(CRnum * i); } } } } |
上記のように複数あったfor文の処理を関数にすることで、一つにまとめることができました。
使用していない処理
リファクタリング対象_2では、コードは書かれていますが、影響を一切与えていない処理となっています。今回の場合は不要なコードなので削除することができます。
実際にC#でリファクタリングを行ってみます。
リファクタリング前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using System; class Program_1 { static void Main(string[] args) { ------------- 同じ処理なので割愛 ------------- LoopX(Cnum); //リファクタリング対象_1 End //リファクタリング対象_2 Start Dnum = 100; for (int d = 1; d >= 10; d++) { if (d < 10) { Console.Write(Dnum * d + "、"); } else { Console.WriteLine(Dnum * d); } } //リファクタリング対象_2 End Console.WriteLine("\r\n" + "計算が完了しました。"); ------------- 同じ処理なので割愛 ------------- } static void LoopX(int CRnum) { ------------- 同じ処理なので割愛 ------------- } } |
リファクタリング後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class Program_1 { static void Main(string[] args) { ------------- 同じ処理なので割愛 ------------- LoopX(Cnum); //リファクタリング対象_1 End //リファクタリング対象_2 Start //削除 //リファクタリング対象_2 End Console.WriteLine("\r\n" + "計算が完了しました。"); ------------- 同じ処理なので割愛 ------------- } static void LoopX(int CRnum) { ------------- 同じ処理なので割愛 ------------- } } |
上記のように不要な記述だったため、削除しても問題ありません。
クラスの肥大化
リファクタリング対象_3では、計算プログラムのクラスに文字合わせプログラムも記述しています。このように一つのクラスに様々な処理を記述しているとクラスが大きく、読みづらくなってしまいます。
今回の場合は文字合わせプログラムを別のクラスに分けることができます。
実際にC#でリファクタリングを行ってみます。
リファクタリング前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
using System; class Program_1 { static void Main(string[] args) { //文字合わせプログラム用 string Astr; string Bstr; string Cstr; //計算プログラム用 int Anum; int Bnum; int Cnum; //文字合わせプログラム起動フラグ string ToolFlgSTR; ------------- 同じ処理なので割愛 ------------- if (ToolFlgSTR == "Y") { Console.Write("\r\n"); } else { Console.WriteLine("プログラムを終了します。"); Environment.Exit(0); } //リファクタリング対象_3 Start //文字合わせプログラム Console.WriteLine("----------文字合わせプログラム----------"); Console.WriteLine("このプログラムでは入力した3つの文字(A、B、C)を、合わせて表示します。"); //コンソールからの値入力_Astr Console.Write("\r\n" + "Aの文字を入力してください:"); Astr = Console.ReadLine(); //コンソールからの値入力_Bstr Console.Write("\r\n" + "Bの文字を入力してください:"); Bstr = Console.ReadLine(); //コンソールからの値入力_Cstr Console.Write("\r\n" + "Cの文字を入力してください:"); Cstr = Console.ReadLine(); //結果表示 Console.WriteLine("\r\n" + "A、B、Cを合わせた値"); Console.WriteLine(Astr + Bstr + Cstr); Console.WriteLine("\r\n" + "合わせ終わりました。"); Console.WriteLine("----------文字合わせプログラム終了----------"); //リファクタリング対象_3 End } static void LoopX(int CRnum) { ------------- 同じ処理なので割愛 ------------- } } |
リファクタリング後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
using System; class Program_1 { static void Main(string[] args) { //文字合わせプログラム用 Program_2 Pro2 = new Program_2(); //計算プログラム用 int Anum; int Bnum; int Cnum; //文字合わせプログラム起動フラグ string ToolFlgSTR; ------------- 同じ処理なので割愛 ------------- if (ToolFlgSTR == "Y") { Console.Write("\r\n"); } else { Console.WriteLine("プログラムを終了します。"); Environment.Exit(0); } //リファクタリング対象_3 Start //Program_2のstrpulsを呼び出し Pro2.strpuls(); //リファクタリング対象_3 End } static void LoopX(int CRnum) { ------------- 同じ処理なので割愛 ------------- } } class Program_2 { public void strpuls() { //文字合わせプログラム用 string Astr; string Bstr; string Cstr; //文字合わせプログラム Console.WriteLine("----------文字合わせプログラム----------"); Console.WriteLine("このプログラムでは入力した3つの文字(A、B、C)を、合わせて表示します。"); //コンソールからの値入力_Astr Console.Write("\r\n" + "Aの文字を入力してください:"); Astr = Console.ReadLine(); //コンソールからの値入力_Bstr Console.Write("\r\n" + "Bの文字を入力してください:"); Bstr = Console.ReadLine(); //コンソールからの値入力_Cstr Console.Write("\r\n" + "Cの文字を入力してください:"); Cstr = Console.ReadLine(); //結果表示 Console.WriteLine("\r\n" + "A、B、Cを合わせた値"); Console.WriteLine(Astr + Bstr + Cstr); Console.WriteLine("\r\n" + "合わせ終わりました。"); Console.WriteLine("----------文字合わせプログラム終了----------"); } } |
上記のように二つに分けることで、計算プログラムに必要な処理、文字合わせプログラムに必要な処理を明確にすることができ、わかりやすくなりました。
リファクタリング後のコード
C#でリファクタリングを行った結果以下のようなコードとなりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
using System; class Program_1 { static void Main(string[] args) { //文字合わせプログラム用 Program_2 Pro2 = new Program_2(); //計算プログラム用 int Anum; int Bnum; int Cnum; //文字合わせプログラム起動フラグ string ToolFlgSTR; //計算プログラム Console.WriteLine("----------計算プログラム----------"); Console.WriteLine("このプログラムでは入力した3つの数字(A、B、C)に、1-10の値を掛けて表示します。"); Console.Write("\r\n" + "Aの値を入力してください:"); //コンソールからの数値入力_Anum Anum = int.Parse(Console.ReadLine()); Console.WriteLine("Aの値に1-10を掛けた値"); //AnumをLoopXに渡し処理をする LoopX(Anum); Console.Write("\r\n" + "Bの値を入力してください:"); //コンソールからの数値入力_Bnum Bnum = int.Parse(Console.ReadLine()); Console.WriteLine("Bの値に1-10を掛けた値"); //BnumをLoopXに渡し処理をする LoopX(Bnum); Console.Write("\r\n" + "Cの値を入力してください:"); //コンソールからの数値入力_Cnum Cnum = int.Parse(Console.ReadLine()); Console.WriteLine("Cの値に1-10を掛けた値"); //BnumをLoopXに渡し処理をする LoopX(Cnum); Console.WriteLine("\r\n" + "計算が完了しました。"); Console.WriteLine("----------計算プログラム終了----------"); Console.Write("\r\n" + "続いて文字合わせプログラムを起動しますか?(Y/N):"); ToolFlgSTR = Console.ReadLine(); if (ToolFlgSTR == "Y") { Console.Write("\r\n"); } else { Console.WriteLine("プログラムを終了します。"); Environment.Exit(0); } //Program_2のstrpulsを呼び出し Pro2.strpuls(); } static void LoopX(int CRnum) { //1-10を掛ける処理_CRnum for (int i = 1; i <= 10; i++) { if (i < 10) { Console.Write(CRnum * i + "、"); } else { Console.WriteLine(CRnum * i); } } } } class Program_2 { public void strpuls() { //文字合わせプログラム用 string Astr; string Bstr; string Cstr; //文字合わせプログラム Console.WriteLine("----------文字合わせプログラム----------"); Console.WriteLine("このプログラムでは入力した3つの文字(A、B、C)を、合わせて表示します。"); //コンソールからの値入力_Astr Console.Write("\r\n" + "Aの文字を入力してください:"); Astr = Console.ReadLine(); //コンソールからの値入力_Bstr Console.Write("\r\n" + "Bの文字を入力してください:"); Bstr = Console.ReadLine(); //コンソールからの値入力_Cstr Console.Write("\r\n" + "Cの文字を入力してください:"); Cstr = Console.ReadLine(); //結果表示 Console.WriteLine("\r\n" + "A、B、Cを合わせた値"); Console.WriteLine(Astr + Bstr + Cstr); Console.WriteLine("\r\n" + "合わせ終わりました。"); Console.WriteLine("----------文字合わせプログラム終了----------"); } } |
実行結果:
———-計算プログラム———-
このプログラムでは入力した3つの数字(A、B、C)に、1-10の値を掛けて表示します。
Aの値を入力してください:10
Aの値に1-10を掛けた値
10、20、30、40、50、60、70、80、90、100
Bの値を入力してください:20
Bの値に1-10を掛けた値
20、40、60、80、100、120、140、160、180、200
Cの値を入力してください:30
Cの値に1-10を掛けた値
30、60、90、120、150、180、210、240、270、300
計算が完了しました。
———-計算プログラム終了———-
続いて文字合わせプログラムを起動しますか?(Y/N):Y
———-文字合わせプログラム———-
このプログラムでは入力した3つの文字(A、B、C)を、合わせて表示します。
Aの文字を入力してください:明日は
Bの文字を入力してください:晴れ
Cの文字を入力してください:ですか?
A、B、Cを合わせた値
明日は晴れですか?
合わせ終わりました。
———-文字合わせプログラム終了———-
リファクタリングを行った結果プログラムが読みやすくなり、結果も変わりません。
エンジニア
マネージャー
C#でリファクタリングを行ってみよう
いかがでしたでしょうか。C#に限らず完成したプログラムを改めて確認すると、同じ処理を繰り返し使っていたり、不要になってしまった処理が存在したりします。
読みづらいコードになってしまうとそれが、原因でバグが発生してしまうこともあります。
ぜひご自身のC#コードを改めて確認して、リファクタリングを行ってみてください。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。

-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。


C#新着案件New Job
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(新宿駅)システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(新宿駅)デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円神奈川県横浜市(桜木町駅)デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円神奈川県横浜市(桜木町駅)基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(西新宿駅)基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(西新宿駅)