【问题标题】:Visual Basic, why can't I import "System.Drawing" when my only reference is "System"?Visual Basic,当我唯一的参考是“System”时,为什么我不能导入“System.Drawing”?
【发布时间】:2012-02-14 09:31:51
【问题描述】:

在 Visual Studio 10 - Visual Basic 中,当我唯一的参考是“System”时,为什么我不能导入“System.Drawing”?我可以导入“System.Runtime.InteropServices”。

重现我的问题:
1. 在 Visual Studio 10 中使用 Visual Basic 类库模板创建一个新项目。
2.开头添加“Imports System.Drawing”和“Imports System.Runtime.InteropServices”。
3.在项目属性的References窗格中删除除“System”之外的所有引用。

结果: Visual Studio 找不到“System.Drawing”,但可以找到“System.Runtime.InteropServices”。 “System.Drawing”是完全限定的,因此系统应该能够在引用的“System”中找到它。

想法: 看起来“System”和“System.Drawing”是不同的命名空间(或容器?)所以为什么不限定“。”工作?做 ”。”代表别的东西?

“系统”也在“mscorlib”中,但这是使用的名称空间还是另一个名称空间?

“Microsoft.VisualBasic”也列在导入的命名空间中,但没有对其的引用。它是如何被发现的? “导入的命名空间”列表是从哪里填充的?

来自 MSDN 库的任何相关信息的链接肯定会有所帮助。我已经浏览了一段时间,但不明白为什么没有导入“System.Drawing”。

【问题讨论】:

    标签: .net vb.net visual-studio-2010 assemblies reference


    【解决方案1】:

    .NET 公共语言基础结构有两个不同的概念:

    • 命名空间:类型名称的前缀,例如System.Drawing,用于区分多个类型,否则它们将具有相同的名称。
    • Assemblies: 可以与其他程序集分开部署、安装和版本控制的代码库。程序集中的类型可以位于任意数量的命名空间中。

    命名空间形成基于句点(点)分隔符的层次结构——因此您应该认为System.Runtime.InteropServices 命名空间中的类型从属于System.Runtime 命名空间中的类型。但是,据我所知,CLI 并不关心名称空间的名称或层次结构,除非它们使您的类型名称独一无二。

    此外,程序集可以包含来自多个命名空间的类型,甚至是不同层次结构中的类型,单个命名空间可以包含在多个程序集中定义的类型。如果您查看 MSDN 文档中的类型.NET 库,它会告诉您该类型在哪个程序集中。但是,as Paolo Falabella has pointed out, MSDN 不会告诉您命名空间在哪个程序集中,因为单个命名空间可以包含来自多个程序集的类型。

    在您的场景中:mscorlib 是一个程序集,它定义了 System 命名空间中的一些类型以及许多其他类型,例如 System.Runtime.InteropServices,正如您所指出的。但是,您在 System.Drawing 命名空间中使用的类型位于 System.Drawing 程序集中。

    由于程序集是代码部署和重用的单元,Visual Studio 项目引用程序集,而不是命名空间,因此您必须在程序的 Visual Studio 项目中添加对 System.Drawing 程序集的引用。

    The VB.NET Imports statement(和它的 C# 等价物,using directive)让您可以引用 命名空间 中的类型,而不必每次都输入命名空间名称。也就是说,使用Imports System.Drawing,您可以在代码中编写Graphics 而不是System.Drawing.Graphics。但这就是 Imports 语句所做的所有。特别是:

    • Imports System 不会自动创建对世界上碰巧在 System 命名空间中定义类型的每个程序集的项目引用。
    • Imports mscorlib 并不意味着您通过短名称引用“mscorlib”程序集中的每个类型。这意味着您可以通过短名称引用“mscorlib”命名空间中的类型,这不仅完全不同,而且不太可能是您想要的。

    底线:如果您想访问 GDI+,则使用 System.Drawing 命名空间中的类型,但该名称与 GDI+ 程序集的名称无关。 Microsoft 为包含 GDI+ 类型的程序集选择了名称“System.Drawing”,但它也可以选择“gdiplus-cli”、“gdi-for-dotnet”甚至“Frobinator”。无论该程序集有什么名称,您都必须添加对该程序集的引用。而且您不会在源代码中这样做 - you add assembly references in your Visual Studio project configuration.

    MSDN has an outdated but still good description of assemblies, namespaces, and the differences between them, which you may find helpful.

    【讨论】:

    • 因此,如果我理解正确,imports System 将引入定义整个 System 命名空间的所有程序集。另一方面,imports mscorlib 只会拉入它的装配定义的部分。
    • 不! Imports 语句仅适用于命名空间。它对程序集一无所知。我将编辑我的答案来解释这一点。
    • 这是一个很有意义的导入区别。在您解释这一点之前,我会说 References 通过提供资源文件位置来使资源可用于导入;然而,这些资源实际上只能通过Imports 语句访问。感谢你付出的努力。以前我发现它们非常令人费解和不清楚。现在引用和导入更有意义了。
    【解决方案2】:

    System.Drawing 命名空间“存在”在另一个 dll 中,该 dll 最初未在类库的模板项目中引用。 您必须添加对System.Drawing 的引用(右键单击项目-> 添加引用;System.Drawing 在 GAC 中)。

    在 MSDN 上,您可以看到每个类“生活”在哪个程序集中。例如,在Bitmap class 的文档中,您可以看到:

    命名空间:System.Drawing

    程序集:System.Drawing(在 System.Drawing.dll 中)

    注意at the namespace level你找不到“Assembly”信息,因为你可以从不同的Assembly中添加类到同一个命名空间。

    【讨论】:

      【解决方案3】:

      System.Drawing 位于您需要引用的单独程序集中。

      【讨论】:

        【解决方案4】:

        即使添加 System.Drawing 作为参考,它仍然不能包含在项目中。

        【讨论】:

          猜你喜欢
          • 2021-03-19
          • 1970-01-01
          • 1970-01-01
          • 2021-09-15
          • 1970-01-01
          相关资源
          最近更新 更多