具有相同名称空间的两个不同的DLL


70

我有两个具有相同名称空间的DLL文件,但是它们具有不同的方法和类型。如何在项目中引用两个DLL并使用它们的方法和类型?

顺便说一下,这两个DLL具有名称相同但实现不同的某些方法和类型,以及一些唯一的方法和类型。


我想到的第一个问题是,为什么要为同一个命名空间创建2个不同的dll?
Searock 2010年

2
他可能只是试图使用碰巧使用相同名称空间的两个。
palswim

我没有创建它。我正在编写一个应使用2个DLL的程序,因为它们在他们的公司中很稳定,所以我不能更改它们。不幸的是,它们都具有相同的文件名和相同的名称空间。

顺便说说。这两个DLL具有相同名称和不同实现的某些函数和类型,以及某些唯一的函数和类型。

10
@Searock-甚至在框架内,尤其是在使用第三方控件时,找到跨越多个程序集的相同名称空间是很常见的。
slugster 2010年

Answers:


99

您不需要做任何特别的事情-只需引用它们并使用类型即可。命名空间可以跨多个程序集毫无问题地出现,因为它们并不是真正的不透明类型。名称空间只是向其包含的所有类型添加通用前缀的一种方法,允许您在不同的名称空间下拥有多个具有相同名称的类型。(该框架不会将它们视为具有相同的名称,因为它会看到所有内容的“完全限定”名称-该名称的前面带有一个别名和一个名称空间。)

在极少数情况下,您引用2个具有相同类型名称相同名称空间的程序集(例如,同一dll的2个不同版本)-您可以使用别名来区分给定类型使用哪个程序集。所有引用的默认别名为global,但是您可以在引用任何程序集时使用别名(使用编译器开关-或仅使用Visual Studio中的属性框)为自己的程序集指定别名,并extern alias <name>在代码文件顶部添加一个子句在哪里使用它-您将使用以下命令从不同的程序集中访问类型<name>::MyNamespace.Type


17
您可以在extern alias此处阅读有关信息:msdn.microsoft.com/en-us/library/ms173212.aspx
porges 2010年

35

如果您有两种类型的名称完全相同(请注意,名称包括名称空间),但使用不同的DLL,并且您有兴趣同时使用这两种类型,则可以执行此操作。

简短答案

您输入Acme.Foo了2个不同的DLL,并且要使用它们。在参考属性窗口(“视图” |“属性”窗口)中为参考指定别名,然后像这样使用它:

extern alias TheAliasYouGaveTheReference

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

默认名称空间适用global于任何C#程序,但请注意,上面我们使用的是创建的别名,而不是global

最好的方法是首先不要陷入这种情况,如果两个程序集都是您自己的,则不要在完全相同的名称空间中创建两个名称完全相同的类型。但是有时我们不控制源代码,因此在那些时候,可以使用上述解决方案。

长答案

我将从此处复制大部分文章,因此将其记录在此处,以防该文章不再可用。

您如何陷入这种情况?

首先,这里是您如何复制场景的方法,因此很清楚我们在说什么:

  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");
            }
        }
    }
    

该类型在应用程序中的用法

好的,现在我们有2个包含的不同程序集Acme.Foo。现在让我们创建一个控制台应用程序,并尝试使用每个应用程序。

  1. 在解决方案资源管理器中右键单击解决方案,然后选择添加|。新项目
  2. 选择一个控制台应用程序并将其命名为Consumer
  3. 右键单击消费者,然后选择“设置为启动项目”
  4. 右键单击Consumer项目中的引用节点,然后选择“添加引用”
  5. 单击项目选项卡,然后多选FooVersion1和FooVersion2单击确定
  6. 将以下行添加到Consumer项目的Program类型的Main中:

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

通过Ctrl + Shift + B(或F6)构建解决方案请注意,您遇到两个构建错误[如下所示]:

在此处输入图片说明

修复

这是我们可以解决的方法:

  1. 打开解决方案资源管理器,然后在Consumer项目的References文件夹中选择FooVersion1。
  2. 点击F4(或选择“视图” |“属性”窗口)
  3. 将别名属性更改为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再次进行构建,请注意仍然没有构建错误

1
谢谢!我以前从未了解过该Alias物业,以前的搜索也没有结果。
托马斯·艾德

5

您可以使用/ reference(导入元数据)(C#编译器选项)编译器选项的别名功能来解决您的问题,请从此处阅读更多详细信息

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.