|
|
連載:C# 2.0入門
第7回 名前空間のエイリアス修飾子と外部アセンブリ
株式会社ピーデー 川俣 晶
2007/11/30 |
|
|
アセンブリ間の名前競合の解決
ここまで見てきた機能は、紛らわしい名前を的確に区別する手段といえる。実際には同じではない名前をうまく区別できない問題を解決する。
しかし、最初から同じ名前が衝突するケースもある。もちろん、通常の開発時にはあり得ない事態である。名前が衝突したらコンパイルが通らないので、たいていはどちらかの名前を変更して回避する。だが、複数の既存のアセンブリを参照して開発を行う場合には修正できない名前の衝突が起こる可能性がある。参照したアセンブリ間の名前の衝突は、それらのアセンブリがバイナリ・ファイルで提供されているとすれば、容易に解決することはできない。
この問題に対処するために用意されたのが「externエイリアス」という機能である。
まず、上記の理由により名前が衝突するケースを見てみよう。
Visual Studio 2005で、コンソール・アプリケーション1つとクラス・ライブラリ2つのプロジェクトを含むソリューションを作成する。コンソール・アプリケーションからは、その2つのクラス・ライブラリのプロジェクトを参照しておく。
以下のような感じである。
|
作成したソリューションの構成 |
Visual Studio 2005で、1つのコンソール・アプリケーション・プロジェクトと2つのクラス・ライブラリ・プロジェクトを含むソリューションを作成する。 |
個々のソース・コードは以下のような内容になっている。
using System;
namespace ClassLibrary
{
public class Class
{
public static void SayHello()
{
Console.WriteLine("Hello in ClassLibrary1!");
}
}
}
|
|
リスト4 ClassLibrary1.Class1.cs |
using System;
namespace ClassLibrary
{
public class Class
{
public static void SayHello()
{
Console.WriteLine("Hello in ClassLibrary2!");
}
}
}
|
|
リスト5 ClassLibrary2.Class1.cs |
using System;
class Program
{
static void Main(string[] args)
{
ClassLibrary.Class.SayHello();
}
}
|
|
リスト6 ConsoleApplication82.Program.cs |
ソリューションをビルドすると次のようなコンパイル・エラーが出る。
エラー 1 型 'ClassLibrary.Class' は '……\ClassLibrary1.dll' および '……\ClassLibrary2.dll の両方に存在します。
|
|
ソリューション(リスト4、5、6)のコンパイル結果 |
この名前の衝突を、2つのクラス・ライブラリを修正することなく解決するには、以下の3つの手順を必要とする。
- 参照にエイリアス名を設定する
- externエイリアスの定義を追加する
- externエイリアスを用いてメソッドを呼び出す
まず、参照にエイリアス名を設定するには、ソリューション・エクスプローラから参照しているアセンブリのプロパティを開く。上記画面の例では、[ConsoleApplication82]−[参照設定]の下の「ClassLibrary1」を右クリックし、メニューから[プロパティ]を選ぶ。
|
ClassLibrary1の参照プロパティ |
コンソール・アプリケーションで参照設定している「ClassLibrary1」を右クリックし、メニューから[プロパティ]を選んで表示する。 |
ここで、[エイリアス]に「global」という名前が入っているが、これをアセンブリを参照するための別の名前に書き換える。参照するアセンブリごとに異なる名前を書き込んでおく。ここでは、「Lib1」という名前を指定しておこう。同様にして、ClassLibrary2については「Lib2」という名前を指定した。
次に、externエイリアスの定義の追加である。これはソース・コードの先頭に以下の2行を追加する。
extern alias Lib1;
extern alias Lib2;
|
|
リスト7 リスト6の先頭に追加するexternエイリアスの定義 |
内容は簡単である。「extern alias」の後に、参照プロパティに書き込んだ名前を書くだけである。これで、ソース・コード内でこの名前を参照する準備ができた。
後は、externエイリアスを用いてメソッドを呼び出すだけである。
// リスト6のコード
ClassLibrary.Class.SayHello();
|
// externエイリアスを用いた呼び出し
Lib1.ClassLibrary.Class.SayHello(); // 出力:Hello in ClassLibrary1!
Lib2.ClassLibrary.Class.SayHello(); // 出力:Hello in ClassLibrary2! |
または
// // externエイリアスを用いた呼び出し(「::」を使用)
Lib1::ClassLibrary.Class.SayHello();
// 出力:Hello in ClassLibrary1!
Lib2::ClassLibrary.Class.SayHello();
// 出力:Hello in ClassLibrary2!
|
|
externエイリアスを用いてメソッドを呼び出す |
externエイリアスの後は「.」でもよいが、名前空間エイリアス修飾子(::)の方が名前衝突のリスクが少ないので好ましいだろう。
このように、アセンブリに付加したエイリアス名を含む名前を使ってアクセスすることで、まったく同じ名前が別個のアセンブリに含まれている場合でも、それらを区別して扱うことができる。
Insider.NET 記事ランキング
本日
月間