【问题标题】:Is System.Collections a "namespace of the System namespace"?System.Collections 是“系统命名空间的命名空间”吗?
【发布时间】:2016-12-04 15:27:31
【问题描述】:

好的,我一直在阅读一本关于 C# 和 .NET 的书,同时学习了 DateTime 结构和以下代码:

DateTime dt = new DateTime(2015, 10, 17);

我问自己“为什么我不用写using System.DateTime在顶部引用它?”

所以我意识到,由于 DateTime 是一个结构,并且“using”关键字用于引用类型(类型是一个通用术语,用于引用集合 {class, interface, structure, enumeration, delegate} 中的成员) ,在特定的命名空间中定义(在这种情况下,DateTime 是来自系统命名空间的类型结构)。

但我注意到在我的文件顶部,找到了以下 using 指令(它们是在我创建 C# 控制台应用程序时自动放在那里的):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

我想知道为什么 using System 后面的 using 指令是必要的,什么时候它们不都在 System 命名空间下,因此它们应该已经被引用?

所以我猜这是因为在它下面声明的所有都是命名空间,而不是来自集合 {class, interface, structure, enumeration, delegate} 的类型。但是将它们称为“命名空间系统(或属于)命名空间系统”是否是错误的,如果是这样,您必须显式引用命名空间的命名空间而不是将它们隐式包含在using System 下的原因是什么? ?

我希望我的问题很清楚,但如果没有,请告诉我,以便我进行编辑。

【问题讨论】:

  • 只是为了澄清你似乎有的一个误解:在你的例子中使用后面的都是命名空间。你永远不会有像using System.DateTime 这样的东西,因为你从来没有使用这种语法的类(或结构)。还有其他使用using 的方法,在msdn.microsoft.com/en-us/library/sf0df423.aspx 中有描述。在名称解析方面,尽管结构和类(以及接口和您能想到的任何其他东西)的工作方式都差不多。

标签: c# .net namespaces


【解决方案1】:

在内部,所有 .net 类型始终具有完整的类型名称;

System.DateTime
System.Collections.Generic.Dictionary<string, int>
System.Threading.Tasks.Task

“usings”的作用是让您“无形地”引用“.”之前的所有内容。特点。所以当你写

DateTime

C# 会尝试

System.DateTime
System.Collections.Generic.DateTime
System.Linq.DateTime
System.Text.DateTime
etc...

因为只有一个存在 (System.DateTime),所以这是一个明确的匹配,C# 知道你在说什么。

如果有两个匹配项,您会收到关于歧义的编译器错误。因此,如果有 System.Threading.Task.DateTime,您的程序将无法编译。

所有这些都为您的问题的答案奠定了基础。如果

using System;

包括它下面的所有内容,那么很难确保事情没有歧义。例如,如果您想区分两个理论课程

System.WebPages.Button
System.Desktop.Button

那么一个普通的旧using System 不会与new Button() 配合得很好。

【讨论】:

    【解决方案2】:

    原因是,如果 不是,在某些情况下,您将无法避免不必要的名称冲突。例如,如果您在 Foo 命名空间中有一个 Baz 类型,在 Foo.Bar 命名空间中有一个 Baz 类型,那么您总是必须完全限定您的类型,例如Foo.BazFoo.Bar.Baz,在您的代码中,这将使 using 指令毫无意义。

    鉴于它的方式,如果您实际上对包含您的类型的两个命名空间都有 using 指令,则您只需要处理名称冲突。

    【讨论】:

      【解决方案3】:

      您不必有其他 using 指令,例如如果你想要一个列表,你可以在你的代码中声明:

      System.Collections.Generic.List<String> listOfStrings = new System.Collections.Generic.List<String>;
      

      要创建一个新列表,但是 using 语句让您可以简单地将其声明为:

      List<String> listOfStrings = new List<String>;
      

      你不能只用后者的原因:

      using System;
      

      是因为 System.Collections.Generic 中可能有一个名为 List 的类,以及 System.Collections.Generic 中的 List 类。如果是这样,当您创建一个新的列表对象时,它如何知道您指的是哪个 List 类?

      所以本质上它们用于防止命名冲突,并使程序员能够将事物分组到逻辑命名的组中,例如输入输出相关类可以在 System.IO 中找到

      【讨论】:

        【解决方案4】:

        创建 using 指令以使用命名空间中的类型,而无需指定命名空间。 using 指令不允许您访问嵌套在您指定的命名空间中的任何命名空间。

        来自 https://msdn.microsoft.com/en-us/library/sf0df423.aspx

        如果我使用 Code 为我的文件夹结构(如 projectName\Code\DBFiles)分配命名空间,也会发生同样的事情;在我的一个控制器上,它不允许我访问 DBFiles 中的类,这就是我将所有类名称空间设置为根命名空间的原因。

        【讨论】:

          猜你喜欢
          • 2018-07-18
          • 2011-12-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-13
          相关资源
          最近更新 更多