今回のテーマ
今回の記事は下記のポリモーフィズムについて解説した記事の続きです。
こちらもCHECK
-
【C# sharp】ポリモーフィズムと抽象クラスの使い方
ChatGPTのAPIを使わずに自動化することが可能です。 下記の本を読めば、ChatGPT4でも料金掛からずに自動化できます!KindleUnlimited会員であれば無料で読めます。 今回のテーマ ...
続きを見る
前回の記事では、抽象クラスを継承したクラスを複数作成し、目的の処理を実装しました。
前回の記事のように継承した子クラスを沢山作らなければ、呼び出し元のMainクラスにif文の条件を沢山追加しなければならないと解説しましたが、
ラムダ式を使用することで、それを解消することが出来ます。
前提の知識としてAction、Funcメソッドの使い方は理解していないといけないので、下記の記事を参考にしてください。
こちらもCHECK
-
【C# sharp Linq】Action、Funcの使い方を徹底解説!
ChatGPTのAPIを使わずに自動化することが可能です。 下記の本を読めば、ChatGPT4でも料金掛からずに自動化できます!KindleUnlimited会員であれば無料で読めます。 Action ...
続きを見る
なので、子クラスを作成せずに1つのクラスでも可能ということです。
それでは、やり方を見ていきましょう。
ラムダ式を使用しない場合
ラムダ式を使用せずに1つのクラスのみで実装した処理は下記となります。
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 |
using System; using System.Collections.Generic; class Program { static void Main(string[] args) { List<Robot> robotlist = new List<Robot>(); robotlist.Add(new Robot("Rockman", "Dr_Light", "Blue")); robotlist.Add(new Robot("Fireman", "Dr_Wily", "Red")); robotlist.Add(new Robot("Iceman", "Dr_Wily", "Blue")); foreach (var robot in robotlist) { Console.WriteLine(robot.getName()); if (robot.getName() == "Rockman") { robot.Attack("チャージショット"); } else if (robot.getName() == "Fireman") { robot.Attack("ファイヤーストーム"); robot.Attack("ストーム"); } else { robot.Attack("ア"); robot.Attack("イ"); robot.Attack("ス"); robot.Attack("クラッシャー"); } } } } class Robot { string name, maker, color; public Robot (string _name,string _maker,string _color) { name = _name; maker = _maker; color = _color; } public string getName() { return name; } public string getMaker() { return maker; } public string getColor() { return color; } public void Attack(string weapon) { Console.WriteLine(weapon); } } |
出力結果
Rockman
チャージショット
Fireman
ファイヤーストーム
ストーム
Iceman
ア
イ
ス
クラッシャー
Mainクラスにif文の沢山追加してひどいことになっています。
このようにしなければならない理由としては、各ロボットでAttackメソッドの処理が違うからこのようにしなければなりませんでした。
この問題を解決するためにラムダ式を使用します。
ロボットクラスにAttackメソッドの処理を保持できるようにすることで実装することが出来ます。
ラムダ式を保持するクラスを作成
ラムダ式を保持するクラスを作成しました。
ロボットクラスにAction型の引数を追加し、AttackメソッドではAction型の引数を呼び出すようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class Robot { string name, maker, color; Action attack; public Robot(string _name, string _maker, string _color,Action _attack) { name = _name; maker = _maker; color = _color; attack = _attack; } public string getName() { return name; } public string getMaker() { return maker; } public string getColor() { return color; } public void Attack() { attack(); } } |
呼び出し元のソースコード
続けて呼び出し元のソースコードを見ていきます。
コンストラクタの引数にAction型の引数がふえたので、各ロボットごとにラムダ式を指定します。
下記のようなソースコードにすることで実装できます。
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 |
using System; using System.Collections.Generic; class Program { static void Main(string[] args) { List<Robot> robotlist = new List<Robot>(); robotlist.Add(new Robot("Rockman", "Dr_Light", "Blue", () => Console.WriteLine("チャージショット"))); robotlist.Add(new Robot("Fireman", "Dr_Wily", "Red", () => { Console.WriteLine("ファイヤー"); Console.WriteLine("ストーム"); })); robotlist.Add(new Robot("Iceman", "Dr_Wily", "Blue", () => { Console.WriteLine("ア"); Console.WriteLine("イ"); Console.WriteLine("ス"); Console.WriteLine("クラッシャー"); })); foreach (var robot in robotlist) { Console.WriteLine(robot.getName()); robot.Attack(); } } } |
出力結果
Rockman
チャージショット
Fireman
ファイヤー
ストーム
Iceman
ア
イ
ス
クラッシャー
目的通りの処理結果が出力できました。
このソースコードでは、各ロボットにラムダ式を作成し、ロボットクラスのAction引数に渡しています。
実際に処理を呼び出す時は全てのロボットに対し、Attackメソッドを指定するだけです。
このようにラムダ式を使用することで、ポリモーフィズムを実現することができます。
まとめ 抽象クラスとラムダ式のどちらを使うべきか
今回はラムダ式を使用し、ポリモーフィズムの処理実装しました。
今回の記事と前回の記事で一つ疑問が残ります。
抽象クラスとラムダ式どちらを使うべきなのか。
結論からいうと、どちらを使ってもいいと思います。
今回のように処理が複雑でない場合は、ラムダ式でいいかもしれません。
例えば、今回の記事のAttackメソッドに該当するメソッドが複数個ある場合は抽象クラスで定義し、実現するべきと思います。
ラムダ式を使用すると、クラスを複数個定義する必要がないので、ソースコードの行は少なく済むので、検討の余地は大いにあるでしょう。
皆さんが作る処理に合わせて、使い分けてください!
if文を無駄に作るのだけは終わりにしましょう!!