C# 为什么一个程序集必须被引用两次?

C# 为什么一个程序集必须被引用两次?,c#,.net,C#,.net,问题 在我看来,每当我创建类库时,它的所有依赖项都应该随之而来。换句话说,我希望只引用一个.dll就可以了。毕竟,我引用的.dll本身构建得很好 不是这样吗?我引用依赖项的所有依赖项,以便使用它 期待着得到启发 问题 为了举例说明,这里有一个例子 ClassLibrary1是一个类库项目,有一个公共类: Class1 ClassLibrary2是同一解决方案中的另一个类库,具有 一个公共类:Class1 这两个类存在于各自的名称空间中 但是,ClassLibrary2引用了ClassLibra

问题

在我看来,每当我创建类库时,它的所有依赖项都应该随之而来。换句话说,我希望只引用一个.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() { }
    }
}


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

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

假设您在解决方案中有两个项目,
ProjectA
ProjectB
。两个项目都引用程序集
Important.dll
。通过这里的引用,我指的是在VS项目中右键单击->添加“引用”。另外,假设
ProjectA
在VS中的解决方案中引用了
ProjectB
。我的意思是,右键单击->添加引用->解决方案->选择
ProjectB

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

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

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

希望这有帮助

更多信息:


应该是这样,但ClassLibrary1.dll必须是可访问的。我想这就是C#和.NET的工作原理
ClassLibrary1
ClassLibrary2
的直接依赖项,
ClassLibrary2
ConsoleApplication1
的直接依赖项,因此
ClassLibrary1
ConsoleApplication1
的间接依赖项。编译器需要知道,在构建特定项目之前,所有依赖项都可用于该项目。确切地说,您必须将所有(直接或间接)使用的库添加到应用程序中。顺便说一句,对于从另一个派生的类使用相同的名称不是一个好主意。如果
ClassLibrary2
在内部使用
ClassLibrary1.Class1
,您是否需要引用
ClassLibrary1
?它们在相同的解决方案中这一事实并不重要。在VS中,项目级别更为重要。每个项目都有自己的依赖项,然后在构建时,编译器将遍历依赖项树并将其所需的所有依赖项复制到输出文件夹。如果一个项目引用了VS中的另一个项目,那么您真正做的就是指向build.dll的位置。对我来说,这听起来像是一个非常非技术性的解释。毕竟,你可以用“这就是xyz的工作方式”来解释一切。这真的是一个评论,你可以用这种方式解释一切。当你有一个更专业的答案时,请告诉我,我一定会评论它。
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();
        }
    }
}