web-dev-qa-db-ja.com

同じネームスペースを持つ2つの異なるDLL

同じネームスペースを持つ2つのDLLファイルがありますが、メソッドとタイプは異なります。プロジェクトで両方のDLLを参照し、メソッドとタイプを使用するにはどうすればよいですか?

ところで、これらの2つのDLLには、同じ名前で実装が異なるいくつかのメソッドと型、およびいくつかの一意のメソッドと型があります。

62
user415789

特別なことは必要ありません-それらを参照し、型を使用するだけです。名前空間は、実際には不透明な型ではないため、問題なく複数のアセンブリにまたがることができます。名前空間は、含まれるすべてのタイプに共通のプレフィックスを追加する方法であり、異なる名前空間で同じ名前の複数のタイプを持つことができます。 (フレームワークはそれらの名前が同じであるとは見なしません。なぜなら、すべての「完全修飾」名を見るからです-エイリアスと名前空間がその前に付いています。)

まれに、同じ型名を持つ2つのアセンブリを参照する場合and同じ名前空間(同じdllの2つの異なるバージョンなど)-特定の型に使用するアセンブリを区別するにはエイリアス。すべての参照のデフォルトのエイリアスはglobalですが、アセンブリを参照するときに(コンパイラスイッチを使用するか、Visual Studioのプロパティボックスを使用するだけで)、extern alias <name>句を使用して独自のエイリアスを指定できます。使用するコードファイルの先頭で-<name>::MyNamespace.Typeを使用して異なるアセンブリの型にアクセスします

87
Mark H

まったく同じ名前の2つのタイプがあり(名前に名前空間が含まれていることに注意してください)、異なるDLLにあり、両方を使用することに興味がある場合は、これを行うことができます。

簡易回答

2つの異なるDLLにAcme.Fooタイプがあり、それらを使用する場合。参照プロパティウィンドウ(参照|プロパティウィンドウ)で参照にエイリアスを指定し、次のように使用します。

extern alias TheAliasYouGaveTheReference

TheAliasYouGaveTheReference::Acme.Foo f = new 
    TheAliasYouGaveTheReference::Acme.Foo();

デフォルトの名前空間は global(C#プログラムの場合) ですが、上記のglobalの代わりに作成したエイリアスを使用していることに注意してください。

最適なアプローチは、[〜#〜] not [〜#〜]そもそもこのような状況に陥ることです。両方のアセンブリが独自のものである場合、作成しないでください。まったく同じ名前空間にまったく同じ名前を持つ2つのタイプ。ただし、ソースコードを制御しない場合があります。そのため、上記のソリューションを使用できます。

ロングアンサー

here からほとんどの記事をコピーしているため、記事が利用できなくなった場合に備えてここに記録されます。

どうやってこのような状況に陥りますか?

まず、シナリオを複製する方法を次に示します。これにより、私たちが何を話しているのかが明確になります。

  1. FooVersion1というC#クラスライブラリを作成します。
  2. Class1.csのテンプレートコードを次のコードに置き換えます。

    using System;
    
    namespace Acme
    {
        public class Foo
        {
            public void Bar()
            {
                Console.WriteLine("Bar");
            }
        }
    }
    
  3. ソリューションエクスプローラーでソリューションを右クリックし、[追加]を選択します。新たなプロジェクト

  4. 現在のプロジェクトを保存します(エクスプレスでのみ適用可能)
  5. 新しいプロジェクトダイアログでクラスライブラリを選択し、プロジェクト名をFooVersion2に変更して[OK]を押します。
  6. Class1.csのコードを次のコードに置き換えます。

    using System;
    
    namespace Acme
    {
        public class Foo
        {
            public void Bar()
            {
                Console.WriteLine("Bar");
            }
    
            public void Goo()
            {
                Console.WriteLine("Goo");
            }
        }
    }
    

アプリケーションでのタイプの使用法

わかりましたので、Acme.Fooを含む2つの異なるアセンブリができました。コンソールアプリケーションを作成して、それぞれを使用してみましょう。

  1. ソリューションエクスプローラーでソリューションを右クリックし、[追加]を選択します。新たなプロジェクト
  2. コンソールアプリケーションを選択し、コンシューマーと呼びます
  3. Consumerを右クリックし、「スタートアッププロジェクトとして設定」を選択します
  4. Consumerプロジェクトの参照ノードを右クリックし、「参照の追加」を選択します
  5. [プロジェクト]タブをクリックし、FooVersion1とFooVersion2を複数選択します[OK]をクリックします
  6. ConsumerプロジェクトのProgramタイプのMainに次の行を追加します。

    Acme.Foo f = new Acme.Foo();
    

Ctrl + Shift + B(またはF6)を使用してソリューションをビルドします。次の2つのビルドエラーが発生することに注意してください。

enter image description here

修正

修正方法は次のとおりです。

  1. ソリューションエクスプローラーを開き、ConsumerプロジェクトのReferencesフォルダーでFooVersion1を選択します
  2. F4を押す(または[表示]メニューの[プロパティウィンドウ]を選択)
  3. AliasesプロパティをFooVersion1に変更します
  4. ソリューションを構築する
  5. Acme.FooはFooVersion2を明確に参照するため、すべてが正しくビルドされます。
  6. ConsumerプロジェクトのProgram.csの先頭に次のディレクティブを追加します。

    extern alias FooVersion1;
    
  7. Acme.Fooの使用法を次のように変更します。

    FooVersion1::Acme.Foo f = new FooVersion1::Acme.Foo();
    f.Bar();
    
  8. 「f」と入力すると、完了リストにはAcme.FooのFooVersion1のメソッドのみが含まれることに注意してください(特にGooは含まれません)。

  9. ソリューションをビルドすると、すべてが正しくビルドされます
  10. 最後に、ConsumerプロジェクトのProgram.csのf.Bar()の下に次のコードを追加します。

    Acme.Foo f2 = new Acme.Foo();
    f2.Goo();
    
  11. F2の完了リストにGooが含まれていることに注意してください。

  12. Ctrl + Shift + Bを使用して再度ビルドし、ビルドエラーがないことを確認します。
27
CodingYoshi

/ reference(メタデータのインポート)(C#コンパイラオプション)コンパイラオプションのエイリアス機能を使用して問題を解決できます。詳細については here を参照してください。

5
Hiber