第10章 名前空間とusing:連載 改訂版 C#入門(3/3 ページ)
.NETの巨大なクラス・ライブラリは名前空間により編成されており、usingはその利用を容易にする。どちらもC#プログラミングにおける必修項目だ。
10-5 不完全な名前空間名とusing
以下はusingの誤った使い方である。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 Sample005
15: {
16: using Space1;
17: class Class1
18: {
19: [STAThread]
20: static void Main(string[] args)
21: {
22: Sub1.Class2.test(); // 型または名前空間名 'Sub1' が見つかりませんでした。ディレクティブを使うかアセンブリ参照を使ってください。
23: }
24: }
25: }
16行目では、Space1というnamespaceがデフォルトであると宣言している。この宣言そのものはエラーではない。なぜなら、Space1に属するクラスは宣言可能であるからだ。しかし、22行目の「Sub1.Class2.test();」という記述はエラーになる。なぜなら、Sub1は名前空間名の一部を成す名前であって、不完全な名前空間名を補うために16行目の宣言が使われることはないからだ。これをエラーなく機能するようにするなら、usingを使わずフルネームを書くか、あるいはusingで完全な名前空間名(この場合は「Space1.Sub1」)を指定する必要がある。
10-6 デフォルト名前空間を指定するusingの複数使用
デフォルト名前空間を指定するusingは、複数記述することができる。これにより、複数のクラス・ライブラリに含まれている多くのメソッドを、どれも短い名前で呼び出すことが可能になる。
しかし、何でもかんでもusingすればよいというものではない。例えば、usingで指定された複数の名前空間内に同じ名前のクラスがある場合、それを呼び出そうとすると、コンパイラはエラーを発する。List 10-6がその一例である。
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 Space2.Sub1
15: {
16: class Class2
17: {
18: public static void test()
19: {
20: Console.WriteLine("Space2.Sub1.Class2.test()");
21: }
22: }
23: }
24:
25: namespace Sample006
26: {
27: using Space1.Sub1;
28: using Space2.Sub1;
29: class Class1
30: {
31: [STAThread]
32: static void Main(string[] args)
33: {
34: Class2.test(); // 'Class2' はあいまいな参照です。
35: }
36: }
37: }
このサンプル・ソースには、3〜12行目で宣言される「Space1.Sub1」という名前空間、14〜23行目で宣言される「Space2.Sub1」という名前空間、(それに加えてMainメソッドを置くためのSample006という名前空間)がある。27〜28行目で、「Space1.Sub1」と「Space2.Sub1」をusingで指定している、その結果、このブロック内にあるメソッドからは、この2つの名前空間に属するメソッドを、名前空間名抜きで自由に呼び出すことが可能になる。だが、この2つの名前空間には同じClass2という名前を持ったクラスが存在する。そこで、このClass2を利用する34行目のようなコードを記述すると、コンパイラは「あいまいな参照」というエラーを出す。これは、正当な指定先候補が複数発見でき、その中でどれが適切なのかコンパイラには判断できなかったことを示す。
このエラーを解決するには、本当に呼び出したいクラスはどれなのか、名前空間名を明示してはっきりさせる必要がある。そのような手順が煩雑に感じられるようなら、別名を宣言するusingの機能を用いて、特定のクラスについて短い名前を宣言して使うとよいだろう。List 10-7は実際にそのように記述した例である。
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 Space2.Sub1
15: {
16: class Class2
17: {
18: public static void test()
19: {
20: Console.WriteLine("Space2.Sub1.Class2.test()");
21: }
22: }
23: }
24:
25: namespace Sample007
26: {
27: using Space1.Sub1;
28: using Space2.Sub1;
29: using MyClass2 = Space1.Sub1.Class2;
30: class Class1
31: {
32: [STAThread]
33: static void Main(string[] args)
34: {
35: MyClass2.test();
36: }
37: }
38: }
これを実行した結果はFig.10-5のようになる。
ここでは、29行目の別名を定義するusingと、35行目でその別名を経由して呼び出している部分に注目していただきたい。
『新プログラミング環境 C#がわかる+使える』
本記事は、(株)技術評論社が発行する書籍『新プログラミング環境 C#がわかる+使える』から許可を得て一部分を転載したものです。
【本連載と書籍の関係について 】
この書籍は、本フォーラムで連載した「C#入門」を大幅に加筆修正し、発行されたものです。連載時はベータ版のVS.NETをベースとしていましたが、書籍ではVS.NET製品版を使ってプログラムの検証などが実施されています。技術評論社、および著者である川俣晶氏のご好意により、書籍の内容を本フォーラムの連載記事として掲載させていただけることになりました。
→技術評論社の解説ページ
ご注文はこちらから
Copyright© Digital Advantage Corp. All Rights Reserved.