【ゲーム開発のためのC#入門講座・応用学習編】名前空間で重複を避けよう(Mac用)【#6】

4.0_C#応用学習編

クラスの基礎はばっちり!

ここまでオブジェクト指向の根幹を支える技術「クラス」について、扱い方やメンバー変数、コンストラクタなどを学んできました。

これでクラスの基本的な使い方はばっちりです。

ただ、オブジェクト指向では基本的に「1クラス=1スクリプトファイル」で管理します。これまでは説明を省くためにひとつのスクリプトファイルの中にすべてまとめてしまっていましたが、それだとどんどんひとつのファイルが大きくなってしまいますよね。どこにどんなコードがあるのか探し出すのも一苦労ですし、部分的な再利用もしにくくなってしまいます。

ということで、複数スクリプトファイルによるプログラム構築を行うこととしましょう。

新しいスクリプトファイルを作成しよう

「Visual Studio Code」のエクスプローラで右クリックメニューの「新しいファイル」という選択肢を押下してください。

名前は「任意のクラス名.cs」を入力しますが、今回は「Random.cs」としましょう。

空の新しいスクリプトファイルが生成されれば成功です。

せっかくなのでクラスをきちんと定義しておきましょう。

namespace Test
{
    public class Random
    {
​
    }
}

おや、新しいキーワード「namespace」がありますね。

これは後程解説しますので、一旦このまま先へ進んでください。

別のスクリプトファイルに定義したクラスを使おう

コンソールアプリは「Program.cs」に記述された命令を実行するアプリです。

そのため、メインとなる処理は「Program.cs」に実装する必要があります。

別のスクリプトファイルに定義したクラスなどはすべて、この「Program.cs」で実行される命令の中で活用していくことになるんですね。

というわけで、早速「Program.cs」の方で、新しく作成した「Random」クラスを使ってみましょう。

エクスプローラから「Program.cs」を開き、初期設定されているコードを消して、下記のコードを実装しましょう。

Random random = new Random();
int result = random.Next(10);
Console.WriteLine(result);

デバッグ実行してランダムな数値がコンソール画面に出力されれば成功です。

これで無事、別のスクリプトファイルに定義したクラスを使うことができましたね!

え、「Random」クラスに「Next」なんてメソッドは実装していない?

というか、初期状態のままだからメソッドは何もないはず?

namespace Test
{
    public class Random
    {
        // ↓メソッドなんてひとつもないよ!
    }
}

そうですね。なので今回使っているのは実は自分達で作った「Random」クラスではなく、Microsoftの誰かさんが作ってくれた「Random」クラスになります。

// ↓この「Random」はMicrosoftの誰かが作ってくれたクラスであって、
//  先程自分達が作成した「Random」クラスではないよ!
Random random = new Random();
int result = random.Next(10);
Console.WriteLine(result);

だとすると、自分達で作った「Random」クラスを使うにはどうすればよいのでしょう?

あいつもこいつも作りたいクラス

こんな風に、自分が作成したいクラスが実は他の誰かの手によって既に作られていた、なんてことは十分考えられます。オブジェクト指向の歴史は比較的浅いとはいえ、これまで無数のプログラマーがいて、日々新しいクラスが作成されている訳ですからね。

しかしこれってコンピュータの立場で考えるとすごく困ったことですよね。「new Random()」という命令を受けた時に、果たしてどの「Random」クラスのインスタンスを生成すればいいのかわからない訳ですから。

かといって、じゃあコンピュータが困らないように同じ名前のクラスは作成できないことにします、なんてことにしてしまうと、早い者勝ちでほとんどの名前が使えないことになってしまいます。めちゃくちゃ不便ですよね。

そこで、同じ名前のクラスを複数作れる方法が考案されました。

それが名前空間です。

名前空間を設定しよう

名前空間って何か抽象的でわかりにくい単語なんですけど、やっていることはすごく単純です。

ようはクラスの所属するグループを決められる機能なんですね。

例えばAさんが作った「Random」は「System」というグループに属している、Bさんが作った「Random」は「Number」というグループに属しているとします。

これなら、例えクラス自体は同じ「Random」という名前であったとしても、「SystemグループのRandom」だとか「NumberグループのRandom」といった指定ができるようになりますよね。

コンピュータ君も、どの「Random」のことだろうと悩まずに済む訳です。

これを定義しているのが先程出来てきた「namespace」というキーワードです。

// ↓名前空間を定義しているよ!
namespace Test
{
    public class Random
    {
        
    }
}

この名前空間は自由に設定・変更することが可能です。

試しに「Number」に変更してみましょう。

// ↓名前空間を「Number」に変更したよ!
namespace Number
{
    public class Random
    {
        
    }
}

そして「Program.cs」のコードを下記のように修正してみてください。

Number.Random random = new Number.Random();
int result = random.Next(10);
Console.WriteLine(result);

このように「名前空間.クラス」と記述することで、どの名前空間に属しているクラスを扱いたいのか、指定することができます。

今度こそ、自分達の作った「Random」クラスのインスタンスを作成する命令になったんですね。

その証拠に、「Next」というメソッドに赤い波線が引かれているかと思います。該当箇所にカーソルをあてると、現在発生しているエラー内容が表示されます。

自分達の作った「Random」クラスには「Next」なんてメソッドはありませんから、エラー内容は正しいですね。

名前空間は入れ子にできる

名前空間は入れ子にすることができます。グループの中にさらに細かいグループを持てる、ということですね。

// ↓Yuumeというグループの中に、
namespace Yuume
{
    // ↓さらにNumberというグループがあり、
    namespace Number
    {
        // ↓そこに所属しているクラスだよ!
        public class Random
        {
​
        }
    }
}

基本的に名前空間は、作者名だったりそこに所属しているクラスの性質を表す単語だったりを指定します。なぜなら、

  • 作者名や会社名などのユニークな名称を使うことで、名前空間までかぶってしまうリスクを下げられる(名前空間までかぶってしまうと本当に判断しようがなくなるので詰み)
  • 性質の近いものをまとめておくと、名前空間から所属しているクラスが想像しやすくなる

という恩恵が得られるからです。

入れ子構造の名前空間から対象クラスを指定する場合は「.」で名前空間を繋ぎます。

Yuume.Number.Random random = new Yuume.Number.Random();

Unityでの活躍ポイント

Unityの場合、アセットストアと呼ばれる場所で他の人が作った画像だったりスクリプトだったりを購入することができます。こういった時に名前空間の設定がないと、他の人達が再利用しようとした時に名前がかぶって使えないなんてことが起きてしまうんですね。

Unityの公式マニュアルでも解説ページが1ページ用意されています。

名前空間 – Unity マニュアル (unity3d.com)

表現が分かり辛いので無理に読まなくてOKですが、色んな人でクラスを再利用するために重要な機能なんだなということがご理解いただければ幸いです。

実践演習

それでは実際に新規のスクリプトファイル生成と名前空間設定をしてみましょう。

演習①新規のスクリプトファイルを生成しよう!

必要に応じて今回の記事を見直しながら、新しいクラス「Pikachu」を作成してください。

演習②名前空間を設定しよう!

演習①で作成したクラス「Pikachu」が、「Nintendo」の「Pokemon」に属するよう名前空間を設定してあげてください。

答え合わせ

演習①②合わせた答えとなります。

namespace Nintendo
{
    namespace Pokemon
    {
        internal class Pikachu
        {
        }
    }
}

まとめ

  • オブジェクト指向では基本的に「1クラス=1スクリプトファイル」で管理する
  • 名前空間とはクラスの属するグループを定義できる機能。この機能のおかげで同名のクラスであっても作成し使うことができる
  • 名前空間は入れ子にすることができ、作者名だったりそこに所属しているクラスの性質を表す単語を設定することが多い

次回は名前空間と関連性の深い「using」について学習します。お楽しみに!

それでは、今回もお疲れ様でした!

また次の記事でお会いしましょう!

Posted by yuumekou