Две разные библиотеки DLL с одинаковым пространством имен
У меня есть два DLL файла, у которых у них одинаковое пространство имен, но у них разные функции и типы.
как я могу ссылаться на обе библиотеки DLL в моем проекте и использовать их функции и типы?
Кстати,
. эти две библиотеки DLL имеют некоторые функции и типы с одинаковым именем и различной реализацией и некоторые уникальные функции и типы
Ответы
Ответ 1
Ничего особенного вам не нужно делать - просто ссылайтесь на них и используйте типы. Пространства имен могут охватывать несколько сборок без проблем, потому что они не очень непрозрачные типы. Пространство имен - это всего лишь способ добавить общий префикс для всех типов, которые он содержит, что позволяет вам иметь несколько типов с тем же именем в разных пространствах имен. (Рамка не считает их одинаковыми именами, потому что она видит "полностью квалифицированное" имя всего, у которого есть псевдоним и пространство имен, прикрепленное к нему.)
В редком случае, когда вы ссылаетесь на 2 сборки, которые имеют те же имена типов и одинаковые пространства имен (например, 2 разных версии одной и той же библиотеки), вы можете отличить, какая сборка используется для заданный тип с использованием псевдонима. Псевдоним по умолчанию для всех ссылок - global
, но вы можете указать свой собственный псевдоним для любой сборки, когда вы ссылаетесь на нее (с помощью переключателя компилятора, или просто используйте окно свойств в Visual Studio), и имеете предложение extern alias <name>
в в верхней части вашего файла кода, где вы его используете, вы получите доступ к типам из разных сборок с помощью <name>::MyNamespace.Type
Ответ 2
Если у вас есть 2 типа с одинаковым именем (обратите внимание, что имя включает пространство имен), но в разных библиотеках DLL, и вы заинтересованы в использовании обоих из них, вы можете это сделать.
Короткий ответ
У вас есть тип Acme.Foo
в двух разных DLL, и вы хотите их использовать. Дайте ссылку псевдониму в окне свойств справки (View | Properties Window), затем используйте его следующим образом:
extern alias TheAliasYouGaveTheReference
TheAliasYouGaveTheReference::Acme.Foo f = new
TheAliasYouGaveTheReference::Acme.Foo();
По умолчанию пространство имен global
для любой программы С#, но обратите внимание, что мы используем псевдоним, который мы создали вместо global
.
Лучший подход - не попасть в такую ситуацию, в первую очередь, если обе сборки являются вашими собственными, тогда не создавайте 2 типа с одинаковым именем в одном и том же пространстве имен. Но иногда мы не контролируем исходный код, так что для тех времен, вышеупомянутое решение может быть использовано.
Длинный ответ
Я копирую большую часть статьи из здесь, поэтому она записывается здесь, если статья больше не доступна.
Как вы попадаете в такую ситуацию?
Во-первых, вот как вы можете реплицировать сценарий, так что действительно понятно, о чем мы говорим:
- Создайте библиотеку классов С# под названием FooVersion1
-
Замените код шаблона в Class1.cs следующим образом:
using System;
namespace Acme
{
public class Foo
{
public void Bar()
{
Console.WriteLine("Bar");
}
}
}
-
Щелкните правой кнопкой мыши по решению в обозревателе решений и выберите Добавить | Новый проект
- Сохранить текущий проект (применим только в экспресс)
- Выберите библиотеку классов в новом диалоговом окне проекта и измените имя проекта на FooVersion2 и нажмите OK
-
Замените код в Class1.cs следующим образом:
using System;
namespace Acme
{
public class Foo
{
public void Bar()
{
Console.WriteLine("Bar");
}
public void Goo()
{
Console.WriteLine("Goo");
}
}
}
Использование типа в приложении
Итак, теперь у нас есть две разные сборки, содержащие Acme.Foo
. Теперь создадим консольное приложение и попытаемся использовать каждый.
Создайте решение с помощью Ctrl + Shift + B (или F6)
Обратите внимание, что вы получаете две ошибки сборки [как показано ниже]:
![введите описание изображения здесь]()
Исправление
Вот как мы можем это исправить:
- Откройте диспетчер решений и выберите FooVersion1 в папке "Ссылки" проекта "Потребительский"
- Нажмите F4 (или выберите View | Properties Window)
- Измените свойство "Псевдонимы" на FooVersion1
- Создайте решение
- Теперь все будет правильно построено, потому что Acme.Foo однозначно относится к FooVersion2
-
Добавьте следующую директиву в начало программы Program.cs в проекте Consumer:
extern alias FooVersion1;
-
Измените использование Acme.Foo на:
FooVersion1::Acme.Foo f = new FooVersion1::Acme.Foo();
f.Bar();
-
Обратите внимание, что при вводе "f. список завершений содержит только те методы в FooVersion1 Acme.Foo(в частности, он не включает Goo)
- Постройте решение, и все будет правильно построено.
-
Наконец, добавьте следующий код в файле f.Bar() в Program.cs проекта Consumer:
Acme.Foo f2 = new Acme.Foo();
f2.Goo();
-
Обратите внимание, что список завершения f2s содержит Goo.
- Снова создайте с помощью Ctrl + Shift + B и обратите внимание, что ошибок сборки нет.
Ответ 3
вы можете использовать функцию псевдонима опции компилятора/Импорт метаданных (С# Compiler Options) для решения ваших проблем, прочитайте здесь для более подробной информации