【问题标题】:Why must an assembly be referenced twice?为什么一个程序集必须被引用两次?
【发布时间】:2016-12-29 15:35:59
【问题描述】:

问题

在我看来,每当我创建一个类库时,它的所有依赖项都应该随之而来。换句话说,我希望只引用一个 .dll 就可以了。毕竟,我引用的 .dll 可以自行构建。

不是这样吗?我引用所有依赖项的依赖项,以便使用它?

期待对此有所启发。

问题

为了说明,这里举个例子。

  • ClassLibrary1 是一个类库项目,有一个公共类: Class1.

  • ClassLibrary2 是另一个类库,在同一个解决方案中,具有 一节公开课:Class1

    这两个类存在于它们自己的命名空间中。

    但是,ClassLibrary2 引用 ClassLibrary1,而 ClassLibrary2.Class1 继承自 ClassLibrary1.Class1

  • ConsoleApplication1 是一个控制台应用程序,在同一解决方案中,引用ClassLibrary2

到目前为止,一切都建立起来了。一切都是同一个框架。

但是,当我尝试启动 ClassLibrary2.Class1 时,出现构建错误:

错误 1 ​​类型“ClassLibrary1.Class1”在程序集中定义 没有被引用。您必须添加对程序集的引用 'ClassLibrary1,版本=1.0.0.0,文化=中性, PublicKeyToken=null'。 ...\ConsoleApplication1\Program.cs 12 4 ConsoleApplication1

代码片段

namespace ClassLibrary1
{
    public class Class1
    {
        public Class1() { }
    }
}

...

namespace ClassLibrary2
{
    public class Class1 : ClassLibrary1.Class1
    {
        public Class1() : base() { }
    }
}

...

namespace ConsoleApplication1
{
    using ClassLibrary2;

    class Program
    {
        static void Main(string[] args)
        {
            // error mentioned previously in post is on following line
            var a = new Class1();
        }
    }
}

【问题讨论】:

  • 应该没有,但 ClassLibrary1.dll 必须是可访问的。
  • 我认为这就是 C# 和 .NET 的工作方式。 ClassLibrary1ClassLibrary2的直接依赖,ClassLibrary2ConsoleApplication1的直接依赖,所以ClassLibrary1ConsoleApplication1的间接依赖。在构建特定项目之前,编译器需要知道所有依赖项都可用于该项目。
  • 确切地说,您必须将所有(直接或间接)使用的库添加到您的应用程序中。顺便提一句。对从另一个派生的类使用相同的名称不是一个好主意。
  • 如果ClassLibrary2在内部使用ClassLibrary1.Class1,是否需要参考ClassLibrary1
  • 它们在同一个解决方案中的事实并不重要。在 VS 中,项目级别更为重要。每个项目都有自己的依赖项,然后在构建时,编译器将遍历依赖项树并将所需的所有依赖项复制到输出文件夹。如果一个项目在 VS 中引用了另一个项目,那么你真正要做的就是指向构建的 .dll 的位置。

标签: c# .net


【解决方案1】:

我会在这里尝试制定一个答案。它有助于查看 VS 中项目级别的依赖关系,希望它会更清楚。

假设您在一个解决方案中有两个项目,ProjectAProjectB。这两个项目都引用了一个程序集Important.dll。这里引用,我指的是如果你右键单击 -> 在 VS 项目中添加“引用”。还假设ProjectA 在我们的VS 解决方案中引用ProjectB。我的意思是,右键单击 -> '添加引用' -> '解决方案' -> 选择 Project B

实际发生了什么?请记住,所有 VS 引用都是帮助编译器找到 .dll 的一种方式。在构建时(编译),VS 将遍历解决方案中需要构建的所有项目(您可以在配置管理器中看到这一点)。它会注意到ProjectAProjectB 都设置为构建。然后它将通过遍历依赖关系树来查看引用部分中的所有直接依赖关系。对于所有设置为“复制本地”(默认为 true)的 VS 引用,它们将被发送到构建文件夹。所以Important.dll 将转到构建文件夹.. 你可能知道这一点。

但是 ProjectA 在 VS 中引用 ProjectB。当您有一个项目引用解决方案中的另一个项目时,您真正要做的就是指向该项目的内置 .dll ......在这种情况下为ProjectB.dll。它与另一个 .dll 没有什么不同。如果您查看ProjectA 中“路径”下的引用部分,您可以看到这一点......它将类似于C:\users\jdwqdwqd\vs\ProjectB\ProjectB\bin\x64\ProjectB.dll。所以这也会被复制到输出文件夹中。

我想有人可能会问“Important.dll 不会与ProjectB.dll? 一起被复制两次。 VS 在这里为您提供了很多帮助,并且会选择正确的 .dll 进行复制。

希望这会有所帮助。

更多信息:

https://msdn.microsoft.com/en-us/library/ez524kew.aspx

【讨论】:

    【解决方案2】:

    这正是 C# 的工作方式。继承规则似乎有偏差。我正在处理一个大型项目,我可以跨多个文件使用类库和命名空间,但我每次都必须引用它们,不管继承如何。这很奇怪也很烦人。也许他们很快就会解决这个问题。

    【讨论】:

    • 对我来说听起来像是一个非常非技术性的解释。毕竟,你可以用“这就是 xyz 的工作方式”来解释一切
    • 这真是一条评论
    • 你可以用这种方式解释一切。当您有更技术性的答案时,请告诉我,我一定会批评它。
    猜你喜欢
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多