名前空間は便利な機能であるが、正面からこの機能を使うと、何を指定するにも名前空間の名前を使うことになり、表記が長くなりがちになる。しかし、ソース・コード上の狭い範囲に着目すれば、そこから参照する名前空間の種類も限られており、長い名前をいちいち書かなくても十分に分かりやすいソースを書くことができる。
C#には、これを支援するためにusingという機能がある。usingには、別名とデフォルト名前空間を記述する機能がある。まず、ここでは別名機能について説明する。
別名機能は、名前空間や、それに属するクラスに対して、1つの名前を宣言する機能を提供している。これによって、「ultra.super.special.long.long.name」というような長い名前空間を頻繁に参照する場合に、もっと短い名前(例えば、longname)を付けることができる。
実際にこの機能を使ってみた例がList 10-3である。
1: using System;
2:
3: namespace Space1.Sub1
4: {
5: class Class1
6: {
7: public static void test()
8: {
9: Console.WriteLine("Space1.Sub1.Class1.test() called");
10: }
11: }
12: }
13:
14: namespace Sample003
15: {
16: using MyClass = Space1.Sub1.Class1;
17: using MySpace1 = Space1.Sub1;
18: using MySpace2 = Space1;
19: // using Class1 = Space1.Sub1.Class1; // 2行下のClass1と名前が同じになるのでエラー
20: // using MySpace3 = MySpace2.Sub1; // usingの対象にusingされたキーワード MySpace2は使用できないのでエラー
21: class Class1
22: {
23: [STAThread]
24: static void Main(string[] args)
25: {
26: MyClass.test();
27: MySpace1.Class1.test();
28: MySpace2.Sub1.Class1.test();
29: }
30: }
31: }
これを実行した結果はFig.10-3のようになる。
usingは、クラスやメソッドの内部には記述できない。そのため、usingは16〜20行目の名前空間宣言直後に記述している。16行目は、「Space1.Sub1.Class1」というクラスにMyClassという短い名前を与えている。これ以後、この名前空間ブロック内では、MyClassと書くだけで、「Space1.Sub1.Class1」を指定したことと同様になる。その結果、26行目のように、「MyClass.test()」という記述によって、「Space1.Sub1.Class1」のtest()メソッドが呼び出される。
17行目は、「Space1.Sub1」という名前空間にMySpace1という名前を付けている。その結果、27行目の「MySpace1.Class1.test()」という記述は「Space1.Sub1.Class1.test()」と等しい意味を持つ。
usingは部分的な名前空間の指定にも使用できる。18行目のSpace1にMySpace2という別名を与えている。その結果、28行目の「MySpace2.Sub1.Class1.test()」は、「Space1.Sub1.Class1.test()」と等しい意味を持つ。
上記の3例は、C#で合法的な書式である。以下では、C#でエラーになってしまう書式を説明する。
19行目に記述した例を、コメント記号を取り去ってコンパイルするとエラーになる。なぜなら、別名として使ったClass1は、21行目ですでにクラス名として宣言済みだからだ。1つの名前空間内では、同じ名前のクラスを使うことができないという原則は、別名にも適用される。
20行目は少しややこしいが、usingのイコール記号の右側では、usingで宣言した別名を使用することはできない、という制約である。「MySpace2.Sub1」のMySpace2は別名なので使用できない。この場合、「Space1.Sub1」と書けばOKである。
実は、usingというキーワードは本連載の第2章から登場している。サンプル・ソースの先頭に、毎回、「using System;」という1行が書き込まれているのを確認していただきたい。このusingは、別名ではなくデフォルトの名前空間を宣言するusingである。
いつも使っているConsole.WriteLineメソッドの本来のフルネームは、「System.Console.WriteLine」となる。しかし、「using System;」という宣言によって、省略された名前空間があった場合に補うべき名前空間はSystemであるという指定がなされており、「System.」を省略した「Console.WriteLine」という記述で、正しいメソッドの呼び出しが実現される。
List 10-4に、1本のソース内で完全に完結するusingの例を示す。
1: using System;
2:
3: namespace Space1.Sub1
4: {
5: class Class2
6: {
7: public static void test()
8: {
9: Console.WriteLine("Space1.Sub1.Class2.test()");
10: }
11: }
12: }
13:
14: namespace Sample004
15: {
16: using Space1.Sub1;
17: class Class1
18: {
19: [STAThread]
20: static void Main(string[] args)
21: {
22: Class2.test();
23: }
24: }
25: }
これを実行した結果はFig.10-4のようになる。
16行目のusingで、「Space1.Sub1」がデフォルトの名前空間であると宣言している。その結果、このブロックに属する22行目では、「Class2.test()」と記述するだけで、自動的に「Space1.Sub1」が補われて、「Space1.Sub1.Class2.test()」が呼び出される。
Copyright© Digital Advantage Corp. All Rights Reserved.