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

63 c# visual-studio-2010 .net-2.0

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

顺便说一句,这两个DLL有一些方法和类型具有相同的名称但不同的实现和一些独特的方法和类型.

Mar*_*k H 93

你不需要做什么特别的事 - 只需引用它们并使用类型.命名空间可以跨越几个程序集而没有问题,因为它们不是真正的不透明类型.命名空间只是为其包含的所有类型添加公共前缀的一种方式,允许您在不同的命名空间下具有多个相同名称的类型.(框架没有看到它们具有相同的名称,因为它看到了所有内容的"完全限定"名称 - 它的前面附有别名和命名空间.)

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

  • 你可以在这里阅读`extern alias`:http://msdn.microsoft.com/en-us/library/ms173212.aspx (15认同)

Cod*_*shi 28

如果您有两个具有完全相同名称的类型(请注意该名称包含名称空间),但在不同的DLL中,您有兴趣同时使用它们,那么您可以执行此操作.

简答

您已键入Acme.Foo2个不同的DLL,并且您想要使用它们.在引用属性窗口(视图|属性窗口)中为引用提供别名,然后像这样使用它:

extern alias TheAliasYouGaveTheReference

TheAliasYouGaveTheReference::Acme.Foo f = new 
    TheAliasYouGaveTheReference::Acme.Foo();
Run Code Online (Sandbox Code Playgroud)

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

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

答案很长

我正在从这里复制大部分文章,因此在此处记录以防文章不再可用.

你怎么陷入这种情况?

首先,这里是你如何复制场景,所以我们正在谈论的是非常清楚:

  1. 创建一个名为FooVersion1的C#类库
  2. 使用以下内容替换Class1.cs中的模板代码:

    using System;
    
    namespace Acme
    {
        public class Foo
        {
            public void Bar()
            {
                Console.WriteLine("Bar");
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 右键单击解决方案资源管理器中的解决方案,然后选择添加| 新项目

  4. 保存当前项目(仅适用于快递)
  5. 在新项目对话框中选择一个类库,并将项目名称更改为FooVersion2,然后按确定
  6. 用以下内容替换Class1.cs中的代码:

    using System;
    
    namespace Acme
    {
        public class Foo
        {
            public void Bar()
            {
                Console.WriteLine("Bar");
            }
    
            public void Goo()
            {
                Console.WriteLine("Goo");
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

在Application中使用类型

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

  1. 右键单击解决方案资源管理器中的解决方案,然后选择添加| 新项目
  2. 选择控制台应用程序并将其命名为Consumer
  3. 右键单击Consumer并选择"Set as startup project"
  4. 右键单击Consumer项目中的references节点,然后选择"Add Reference"
  5. 单击项目选项卡,然后多选FooVersion1和FooVersion2单击确定
  6. 在Consumer项目的Program类型中将以下行添加到Main:

    Acme.Foo f = new Acme.Foo();
    
    Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

修复

以下是我们如何解决它:

  1. 打开解决方案资源管理器,在Consumer项目的References文件夹中选择FooVersion1
  2. 点击F4(或选择View | Properties Window)
  3. 将Aliases属性更改为FooVersion1
  4. 构建解决方案
  5. 现在一切都会正确构建,因为Acme.Foo明确地引用了FooVersion2
  6. 将以下指令添加到Consumer项目的Program.cs顶部:

    extern alias FooVersion1;
    
    Run Code Online (Sandbox Code Playgroud)
  7. 将Acme.Foo的用法更改为:

    FooVersion1::Acme.Foo f = new FooVersion1::Acme.Foo();
    f.Bar();
    
    Run Code Online (Sandbox Code Playgroud)
  8. 请注意,当您键入"f"时 完成列表仅包含Acme.Foo的FooVersion1中的那些方法(特别是它不包括Goo)

  9. 构建解决方案,一切都将正确构建
  10. 最后在Consumer项目的Program.cs中的f.Bar()下添加以下代码:

    Acme.Foo f2 = new Acme.Foo();
    f2.Goo();
    
    Run Code Online (Sandbox Code Playgroud)
  11. 请注意,f2的完成列表包含Goo.

  12. 使用Ctrl + Shift + B再次构建,并注意仍然没有构建错误


Hib*_*ber 5

您可以使用/引用(导入元数据)(C#编译器选项)编译器选项的别名功能来解决你的问题,从阅读这里了解更多详情