为什么我不需要在测试 class 文件中添加主项目的命名空间?

Why don't I need to add my main project's namespace in the test class files?

希望这是一个基本问题,但我找不到答案...

This Microsoft documentation 让我相信我需要为我的主项目的命名空间添加一个 using 指令到我的测试 class 文件,以便能够访问主项目成员。

using MainProject;

namespace MainProject.Tests;

[TestClass]
public class UnitTests
{
    ...
}

但是,当我这样做时,Visual Studio 代码(带有 Microsoft C# 扩展名)告诉我 MainProject 导入是不必要的。事实上,我的单​​元测试设法在没有 using 语句的情况下访问主要项目成员。

主项目和测试项目都存在于单独的目录中,并且有单独的 .csproj 文件。两者都位于包含一个 .sln 文件的父文件夹中,每个文件都已添加到该文件中。测试项目的 .csproj 文件引用了主项目的文件。

主项目的命名空间是:MainProject

测试项目的命名空间是:MainProject.Tests

我在测试项目文件中选择了全局使用,并且有一个 usings.cs 文件,其中包含一行:

global using Microsoft.VisualStudio.TestTools.UnitTesting;

奇迹发生在哪里? (例如,是否有“子”命名空间自动“继承”父命名空间中声明的类型的规则?)

非常感谢您的帮助。

简单的 using 语句将命名空间引入 名称解析 的范围内,它与目录或程序集无关。

命名空间做同样的事情,除了它有层次结构的基础,因此不那么灵活。

本质上没有魔法,你误会了。

我找到了解释命名空间范围“嵌套”的官方文档,并且内部命名空间可以访问外部命名空间的成员。这里是: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/basic-concepts#77-scopes

(第 7.7.1 节中的第二个要点描述了该规则。)

很久以前我上次使用 C# 时,它与 Java 非常相似,几乎无法区分。但是很多都变了。

例如,我忘记了 Java-style 命名空间声明是最近添加到 dotnet 的:

namespace MyCompany.MyProduct;
...

我们曾经不得不这样做:

namespace MyCompany
{
    namespace MyProduct
    {
        ...
    }
}

这样看,很容易理解为什么人们可能会隐含地假定内部作用域可以访问外部作用域的成员,而无需阅读语言规范中的规则。例如,如果您习惯于 Java编写作用域脚本,并且您的命名空间心智模型与上述类似,那么这个想法似乎很自然。

但是,如果您习惯了 Java 中包导入的工作方式,那么这看起来会很奇怪。