【ゲーム開発のためのC#入門講座・応用学習編】名前空間を省略できるようにしよう(Mac用)【#7】

4.0_C#応用学習編

おさらい

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

前回はクラス名の重複を避けるための仕組み、名前空間について学びました。

このおかげで、例え同じ名前のクラスがあっても、どのクラスなのかを明確にすることができます。これにはコンピュータ君もにっこりですね。

同名がいるならばわかるけども……

一方で、この名前空間が長くなればなるほど、コードを書く手間は増えます。

// なげえ!
Yuume.Number.Random random = new Yuume.Number.Random();

上記のように名前が重複しているクラスであれば仕方がありません。が、実際には名前の重複がないクラスまで毎回名前空間を書かなければいけないとしたら、それってすごく面倒ですよね。

ようは同姓同名が一人もいないのに、常にフルネームで呼び合っているような状態です。長く付き合っていくなら、もっとフレンドリーにいきたいところ。

そこで名前空間を省略するための機能がC#では提供されています。

それがusingです(日本語名とかはないみたいですね)。

usingで名前空間を省略しよう

前回作成したプロジェクトを開いてください。

その上でまた新しいクラス「TextDecorator.cs」を追加しましょう。

namespace Test
{
    public class TextDecorator
    {
        public string Decorate(string text)
        {
            return "「" + text + "」";
        }
    }
}

テキストに「」をつけて台詞っぽくしてくれるクラスですね。

早速「Program.cs」の方で使ってみましょう。

下記コードを張り付けた上でF5キーでデバッグ実行してみてください。

Test.TextDecorator textDecorator = new Test.TextDecorator();
string text = textDecorator.Decorate("いけ、フィンファンネル!");
Console.WriteLine(text);
コンソール画面

「いけ、フィンファンネル!」

今は名前空間「Test」からフルネームで記載を行っていますね。

このように、各クラスを使った命令は本来、名前空間も含めてフルネームで記述しなければなりません。クラスの重複を避けるためとはいえ、毎回書くのは正直かなりだるいです。

少しでも楽するために、そのスクリプト内で使いたい名前空間だけは省略して記述できるようにしておこう、というのが「using」という機能です。

その性質上、スクリプトファイルの先頭にしか記述できないという点にご注意下さい。

// プログラムの先頭じゃないとだめだよ!
using Test;
​
// 最初に宣言しておけば、名前空間を省略できる!
TextDecorator textDecorator = new TextDecorator();
string text = textDecorator.Decorate("いけ、フィンファンネル!");
Console.WriteLine(text);

きちんと省略してもエラーにならずに実行できますね。

長い名前空間や入れ子の名前空間に属している場合、この「using」を使わないと入力が手間になってしまいます。ぜひ活用していきましょう。

なお、同じ名前空間に所属しているものは「using」を必要としません。自分自身が属しているものなので、わざわざ名前空間の利用を宣言する必要がない、ということですね。

そういえば、省略されたものといえば……

そういえば身近にひとつ、Visual Studio Codeに移行したら急に省略されるようになったものがありましたね。

そう、「System.Console.WriteLine」の「System」です。

実はこれも名前空間なのです。

あれ、でも「using System;」とは一切記述していないよ? と思った方、素晴らしい気づきです。

実は最近の仕様変更により、暗黙のglobal usingというものが実装されました。

実はこのusingというのは個々のスクリプトファイル単位で記述しなければいけないルールになっています。

そのため、これまでのプログラムは個々のスクリプトファイルに毎回同じようなusingを書いていました。

どうせどのプログラムでも使うものなら一箇所でまとめて定義できるようにならないか、ということから導入されたのがglobal usingです。

そしてその中でもこれは必ず使うから最初からglobal usingに指定しておくよ、とMicorosftが決めたものが暗黙のglobal usingと呼ばれるものなっています。

「System」はそんな暗黙のglobal usingの対象に含まれているんですね。

だからVisual Studio Codeに移行した途端、急に省略できるようになったのです。それが環境構築編でお伝えしていた下記の理由です。

2行目は「System」という文言がカットされてはいますが、これまでも使ってきた「System.Console.WriteLine」が記述されています。なぜ「System」がカットされているのかは応用編で解説予定なので、今は「コンソールアプリでは書かなくていいらしい」と思ってもらえればOKです。

一見すると便利そうなんですが、しょせんは一部なんですよね。それに完全に名前空間やusingのことを意識せずにコーディングができるのかというと、全然そんなことはない訳で。

中途半端に名前空間を設定したり隠蔽したりすると、むしろ未経験者・初心者からすると変に学習コストが高くなるばかりで困るんだが? というのが今回記事を書いていて非常に苦労した僕の愚痴です(死

それはさておき、理屈を理解してしまえばいちおう便利な機能です。

ただ、本来は「System.Console.WriteLine」も名前空間から記述しなければいけないこと、省略するなら「using System;」と記述する必要があることはご理解いただければと思います。

// 本当はこんな風にusing指定しないと、
using System;
​
// 名前空間は省略できないよ!
Console.WriteLine("hoge");
// でも今は暗黙のglobal usingがあるから、
// 「System」の名前空間は勝手に省略できるようになっているよ!
Console.WriteLine("hoge");

ただし注意点として、暗黙のglobal usingで指定されている名前空間に所属するクラスと同名のクラスをusing指定して使おうとすると、必ず名前の衝突が発生してしまうという点に注意してください(例:前回作成したRandom)。

using Yuume.Number;

// 名前空間をどちらも省略できるようにすると、
// 結局どっちのRandomクラスなのかわからなくなっちゃうからエラーになる!
Random random = Random();
int result = random.Next(10);
Console.WriteLine(result);

やっぱりありがた迷惑

その場合はフルネームで記述し、衝突を避けられるようにしてあげましょう。

Unityでの活躍ポイント

Unity Technologiesが提供してくれるクラス群もいくつかの名前空間にまとめられています。そのため、それらの名前空間に属するクラスを利用する場合は利用したい名前空間を「using」で宣言しておくのが基本となります。

// Unityでよく利用する名前空間
using UnityEngine;
using UnityEngine.UI;

この「using」を書いておかないと、各命令でいちいち「UnityEngine.クラス名」とか「UnityEngine.UI.クラス名」なんて書かなければいけなくなってしまうので、忘れずに記述しておきましょう。

まとめ

  • 「using」とは使いたい名前空間の記述を省略できる機能
  • 本来は名前空間も含めてフルネームで記述しなければならないが、毎回フルネームは辛いので、指定した場合のみ省略できるようになっている
  • 「global using」という、若干迷惑だけどいちおうありがたい機能が導入されたため、これまでは名前空間を記述しなくても命令を実行することができた

今回は実践演習なしです。

次回、応用学習編は最終回となります。

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

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

続きはこちらからどうぞ!

Windows版と共通の記事に戻ります。

続きはこちらからどうぞ!

Posted by yuumekou