gpt4 book ai didi

c# - 使用命名空间时 C# 编译的内容

转载 作者:行者123 更新时间:2023-12-04 16:54:10 24 4
gpt4 key购买 nike

我们有两个应用程序,每个应用程序都编译自己的代码,其中一些代码是共享的(主要是数据相关的)。将此设计拆分为三个命名空间并尝试强制执行该命名空间 Foo 感觉很自然。从不导入命名空间 Bar但两者都可以导入命名空间 Shared .

我希望维恩图作为一种可视化而受到赞赏:
enter image description here

但是 Foo 之间的类之一和 Bar从裂缝中溜走,有人引用了 Bar 中的一个类内Foo尽管执法。

这让我想知道 C# 编译器实际上是如何处理这个问题的?在我看来,两件事之一可能会发生。

  • 整个命名空间被编译成 Foo .让图表看起来像这样:
    enter image description here
  • 或者编译器足够聪明,只是为了提取必要的类。使图表看起来像这样:
    enter image description here

  • 我似乎找不到关于 using 和命名空间如何编译的任何文档。似乎命名空间只是为开发人员而不是编译器组织代码。然而他们提供了范围......所以我猜#2适用吗?如何测试这个?

    最佳答案

    命名空间和程序集之间没有对应关系:一个程序集可以包含多个命名空间,一个命名空间可以跨越多个程序集。

    程序集中已编译的 IL 代码通过完全限定名称引用类型:Foo.SomeClass而不是 SomeClass , Bar.OtherClass而不是 OtherClass , 等等。编译器的工作是找出您在编写缩写形式 SomeClass 时真正指的是哪个完全限定类型名称。 -- 因为你可以定义一个名为 SomeClass 的类在命名空间 Foo , Bar ,甚至 System !

    当你写:

    namespace Foo
    {
    public class SomeClass
    {
    }
    }

    您正在定义一个具有完全限定名称的类型 Foo.SomeClass .

    当你写:

    using Foo;
    ...
    SomeClass instance = new SomeClass();

    编译器将其视为:

    Foo.SomeClass instance = new Foo.SomeClass();

    命名空间只是为了方便组织这些完全限定名称的一种构造。当你说 using Foo; ,您只是告诉编译器搜索以 Foo. 开头的完全限定名称。每当您输入 SomeClass .当你写 using Foo; 时,没有任何东西被“导入” ,它只是提供了一种方便的替代写作方式 Foo.SomeClass到处;您的 using 也不会生成任何“代码”(在发出 IL 指令的意义上)。 s 或您的 namespace s。它所做的只是告诉编译器放置 Foo.SomeClass每当你写 SomeClass 到 IL .

    以上是规范中定义的一组更细微的规则的简化,用于解析短格式类型名称;您可以阅读本文了解更多详情: herehere

    您希望在图表中强制执行依赖项的级别将是程序集引用级别:如果 Foo 项目从不引用 Bar 程序集,反之亦然,如果您尝试引用类型,则代码甚至不会编译一个组件来自另一个。命名空间与此没有太大关系,因为同样,没有什么能阻止您在 Foo 中定义类型。命名空间但在 Bar部件。

    关于c# - 使用命名空间时 C# 编译的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62050990/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com