連載:C# 2.0入門

第7回 名前空間のエイリアス修飾子と外部アセンブリ

株式会社ピーデー 川俣 晶
2007/11/30
Page1 Page2 Page3

アセンブリ間の名前競合の解決

 ここまで見てきた機能は、紛らわしい名前を的確に区別する手段といえる。実際には同じではない名前をうまく区別できない問題を解決する。

 しかし、最初から同じ名前が衝突するケースもある。もちろん、通常の開発時にはあり得ない事態である。名前が衝突したらコンパイルが通らないので、たいていはどちらかの名前を変更して回避する。だが、複数の既存のアセンブリを参照して開発を行う場合には修正できない名前の衝突が起こる可能性がある。参照したアセンブリ間の名前の衝突は、それらのアセンブリがバイナリ・ファイルで提供されているとすれば、容易に解決することはできない。

 この問題に対処するために用意されたのが「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エイリアスの後は「.」でもよいが、名前空間エイリアス修飾子(::)の方が名前衝突のリスクが少ないので好ましいだろう。

 このように、アセンブリに付加したエイリアス名を含む名前を使ってアクセスすることで、まったく同じ名前が別個のアセンブリに含まれている場合でも、それらを区別して扱うことができる。


 INDEX
  C# 2.0入門
  第7回 名前空間のエイリアス修飾子と外部アセンブリ
    1.未来志向/バージョンによるコード破壊/グローバルな名前空間の強制
  2.アセンブリ間の名前競合の解決
    3.アセンブリ内部へのアクセス/フレンド・アセンブリ/アクセスを制限する価値
 
インデックス・ページヘ  「C# 2.0入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間