две разные DLL с одинаковым пространством имен - PullRequest
61 голосов
/ 09 сентября 2010

У меня есть два DLL-файла, которые имеют одинаковое пространство имен, но имеют разные методы и типы.Как я могу ссылаться на обе библиотеки DLL в моем проекте и использовать их методы и типы?

Кстати, эти две библиотеки DLL имеют несколько методов и типов с одинаковым именем, но разной реализацией и некоторыми уникальными методами и типами.

Ответы [ 3 ]

86 голосов
/ 09 сентября 2010

Ничего особенного вам не нужно делать - просто ссылайтесь на них и используйте типы. Пространства имен могут без проблем охватывать несколько сборок, потому что они не совсем непрозрачные типы. Пространство имен - это просто способ добавления общего префикса ко всем содержащимся в нем типам, что позволяет вам иметь несколько типов одного и того же имени в разных пространствах имен. (Фреймворк не видит, что они имеют одинаковые имена, потому что он видит «полностью определенное» имя всего - с псевдонимом и пространством имен, прикрепленными к его передней части.)

В том редком случае, когда вы ссылаетесь на 2 сборки, которые имеют одинаковые имена типов и в одних и тех же пространствах имен (например, 2 разных версии одной и той же библиотеки DLL) - вы можете различить, какую сборку использовать для данного введите псевдоним. Псевдоним по умолчанию для всех ссылок - global, но вы можете указать свой собственный псевдоним для любой сборки, когда вы ссылаетесь на нее (используя переключатель компилятора - или просто используете поле свойств в Visual Studio) - и имеете предложение extern alias <name> в верхняя часть вашего файла кода, где вы его используете - вы получите доступ к типам из разных сборок с помощью <name>::MyNamespace.Type

26 голосов
/ 26 июля 2017

Если у вас есть 2 типа с одинаковым именем (обратите внимание, что имя включает пространство имен), но в разных DLL, и вы заинтересованы в использовании обоих из них, то вы можете сделать это.

Короткий ответ

У вас есть тип Acme.Foo в 2 разных DLL, и вы хотите их использовать. Задайте для псевдонима ссылку в окне свойств ссылки (Окно просмотра | Свойства), затем используйте его следующим образом:

extern alias TheAliasYouGaveTheReference

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

Пространство имен по умолчанию - global для любой программы на C # , но обратите внимание, что выше мы используем созданный псевдоним вместо global.

Наилучший подход заключается в том, чтобы НЕ вообще попасть в подобную ситуацию, если обе сборки являются вашими собственными, то не создавайте 2 типа с одинаковыми именами в одном и том же пространстве имен. Но иногда мы не контролируем исходный код, поэтому для этого времени можно использовать вышеуказанное решение.

Длинный ответ

Я копирую большую часть статьи из здесь , поэтому она записывается здесь в случае, если статья больше не доступна.

Как вы попали в такую ​​ситуацию?

Во-первых, вот как вы можете повторить сценарий, чтобы было действительно ясно, о чем мы говорим:

  1. Создание библиотеки классов C # с именем FooVersion1
  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");
            }
        }
    }
    

Использование типа в приложении

Хорошо, теперь у нас есть 2 разные сборки, содержащие Acme.Foo. Теперь давайте создадим консольное приложение и попробуем использовать каждое из них.

  1. Щелкните правой кнопкой мыши решение в обозревателе решений и выберите Добавить | Новый проект
  2. Выберите консольное приложение и назовите его Consumer
  3. Щелкните правой кнопкой мыши на Consumer и выберите «Установить как стартовый проект».
  4. Щелкните правой кнопкой мыши узел ссылок в проекте Consumer и выберите «Добавить ссылку»
  5. Нажмите на вкладку проектов и выберите несколько объектов FooVersion1 и FooVersion2. Нажмите ОК
  6. Добавьте следующую строку в Main в типе программы проекта Consumer:

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

Постройте решение с помощью Ctrl + Shift + B (или F6) Обратите внимание, что вы получаете две ошибки сборки [как показано ниже]:

enter image description here

Исправление

Вот как мы можем это исправить:

  1. Откройте обозреватель решений и выберите FooVersion1 в папке «Ссылки» проекта «Потребитель»
  2. Нажмите F4 (или выберите View | Properties Window)
  3. Измените свойство псевдонимов на FooVersion1
  4. Постройте решение
  5. Теперь все будет работать правильно, потому что Acme.Foo однозначно относится к FooVersion2
  6. Добавьте следующую директиву в начало Program.cs в проекте Consumer:

    extern alias FooVersion1;
    
  7. Измените использование Acme.Foo на:

    FooVersion1::Acme.Foo f = new FooVersion1::Acme.Foo();
    f.Bar();
    
  8. Обратите внимание, что когда вы набираете «f», список завершения содержит только те методы в FooVersion1 из Acme.Foo (в частности, он не включает Goo)

  9. Постройте решение, и все будет работать правильно
  10. Наконец добавьте следующий код в f.Bar () в Program.cs проекта Consumer:

    Acme.Foo f2 = new Acme.Foo();
    f2.Goo();
    
  11. Обратите внимание, что список завершения f2 содержит Goo.

  12. Выполните сборку снова, используя Ctrl + Shift + B, и обратите внимание, что все еще нет ошибок сборки
5 голосов
/ 09 сентября 2010

вы можете использовать псевдоним опции компилятора / reference (Import Metadata) (C # Опции компилятора), чтобы решить ваши проблемы, прочитайте здесь для более подробной информации

...