【问题标题】:What is the point of references in Visual Studio?Visual Studio 中的引用点是什么?
【发布时间】:2019-12-09 07:42:03
【问题描述】:

有点傻的问题,但我还是看不懂。

假设我有 A.exe 文件和 B.dll 文件。 B.dll 位于 ../Somewhere/Debug/B.dll

我从我的 A.exe 项目中引用了这个 .dll,但是当我执行 A.exe 时,它会查找 B.dll A.exe 所在的同一目录中。那么为什么我必须在我的 A.exe 中指定 B.dll (../Somewhere/Debug/B.dll) 的路径> 项目如果它实际上不使用它?

我可以使用 CopyLocal = true 构建引用 ../Somewhere/Debug/B.dllA.exe。然后,我可以对 B.dll 进行更改(例如添加一个新类)并构建它。之后,我可以在我的 A.exe 项目中使用该新类,但如果我在 B.dll 上设置 CopyLocalB.dll 的引用strong>false 并构建 A.exe,一旦我尝试执行 A.exe,我将面临 TypeLoadException,因为它使用旧版本的 B.dll,它位于 A.exe 所在的同一文件夹中。

与位于 GAC 中的强命名程序集相同。我引用了这个程序集(例如 ../Test/My.dll),但 CLR 仍然使用位于 GAC 中的程序集。

Visual Studio 中的引用是否起任何作用,或者它们只是用于开发目的(如 IntelliSense)?

【问题讨论】:

  • 编译器需要知道要链接到哪些程序集,因此它知道在哪里查找您正在使用的类。试着去掉所有的引用,看看你的项目是否成功。

标签: c# .net visual-studio dll


【解决方案1】:

对程序集(也称为 DLL 或 EXE)的引用有两种使用方式。让我们举个例子。在B.dll 中,我们有一个名为ClassB 的类,它有一个公共默认构造函数和一个公共方法(ClassB.MethodB),它接受一个字符串并具有一个void 返回类型。

A.exe 中,代码实例化ClassB 的一个实例并在该实例上调用MethodB

var b = new ClassB();
b.MethodB("SomeString");

在编译时,编译器需要知道ClassB的存在,以及它的公共方法/属性/等等。是。在 C++ 中,这将被编码在一个 H 文件中。在 COM 中,它将位于类型库中。在 .NET 语言(VB、C# 等)中,它在程序集本身中作为 元数据 公开。

因此,当您将A 项目编译成A.exe 时,您需要向编译器提供对B.dll 程序集的引用;这就是编译器知道B 是什么的方式。请注意,其中没有特定于 Visual Studio 的内容;如果您要使用 csc.exe(C# 编译器)执行此操作,您仍然需要在命令行中包含引用。

但是,除此之外,当A.exe 运行时,运行时需要加载并JIT B.dll 程序集,以便当A.exe 中的b.MethodB("SomeString"); 行代码运行时,它可以调用正确的方法在B.dll。 (JIT 意味着即时编译——这在这里真的不相关)

正如@waleedNaveed 指出的那样,如果程序集是否被强命名,运行时行为是不同的。特别是,强名称程序集的运行时程序集搜索路径以 GAC 开头。

对于非强命名程序集,查找引用程序集的最简单位置是与当前执行的程序集位于同一文件夹中。这就是您通常将“本地复制”设置为 true 的原因;它使它正常工作

【讨论】:

    【解决方案2】:

    回答您对 GAC 的困惑。 .NET 框架首先在 GAC 中搜索 dll(程序集)(显然,如果它是强命名的)。如果在 GAC 中未找到程序集,并且如果存在 .config 文件,则 .NET 框架会在配置文件中搜索该位置,否则 .NET 框架会在包含可执行文件 (.exe) 的目录中搜索该程序集。即使在可执行目录中找不到该程序集,也会报错。

    希望能回答您的问题并消除您的困惑。

    【讨论】:

      【解决方案3】:

      每次编译解决方案时,编译器都会复制 B.dll

      目标是允许您在解决方案之外的某个地方定位 dll。例如,这个 dll 可以由另一个团队维护。 (但在这种情况下,内部 nuGet 包会是更好的解决方案。)

      请注意,在编译文件夹中引用 dll 不是一个好主意,因为此文件夹的内容可以在编译之间清除。在这种情况下,您对引用的 dll 使用源代码控制,此文件夹中 dll 上的只读标志可能会导致编译问题。

      【讨论】:

        猜你喜欢
        • 2011-12-28
        • 1970-01-01
        • 2015-12-03
        • 1970-01-01
        • 2012-03-14
        • 2011-06-11
        • 2019-08-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多