在 c# 中,您可以在文件 a.cs(其命名空间为 MyApp.A)中拥有一条语句:
using MyApp.B;
而文件 b.cs(其名称空间为 MyApp.B)已经包含该语句
using MyApp.A;
如果类似的依赖关系存在于不同的 dll 中(其中 a.dll 引用 b.dll,反之亦然),则由于循环依赖错误,它不会被允许,那么为什么命名空间允许它(编译器不允许)甚至产生警告)?无论如何,这样做不是有代码味道吗?
达米安不信者 wrote 命名空间是功能的逻辑分组.
汉斯·帕萨特 wrote 命名空间只不过是对编译器的一个简单提示.
我想详细说明一下,这实际上取决于您认为自己是什么成分在您的代码库中。 A成分是一组类型。 A成分可以生成一个或多个程序集中定义的一个或多个命名空间。重要的是组件之间不存在依赖循环。因为组件是一个发展单位,如果A、B两部分相互利用,则构成一个更大的发展单位,它们不能独立开发,它们形成一个超级组件或者换句话说,这是意大利面条代码.
为了回答你的问题,为什么 C# 中的命名空间允许循环依赖? the implicit你的问题背后的陈述是命名空间用于定义逻辑组件。但是命名空间也可以用来避免类型名称冲突,以结构化的方式呈现公共 API 的类,过滤一组扩展方法......因此我猜答案是C# 设计者当然不想将命名空间的概念仅限于逻辑组件化.
顺便说一句,许多开发人员正在使用以下概念:项目/装配定义组件。恕我直言,这是错误的,因为组装是一个物理概念,伴随着成本和维护(版本控制、部署、编译、动态 CLR 加载...)。装配体作为physical概念应该用于physical原因(例如部署单元、API 单元、插件实现、代码/测试分离...)。我写两本白皮书 http://www.ndepend.com/docs/white-books在此程序集 vs 命名空间 vs 组件如果您感兴趣的话。
无论如何,这样做不是有代码味道吗?
在我看来是的,因为如果一个大型程序集包含许多具有依赖循环的命名空间,那么人们就无法尝试从代码中理解整体架构。我正在开发一个名为 NDepend 的 .NET 静态分析器,它可以检查命名空间依赖循环 http://www.ndepend.com/features/dependency-cycles#DependencyCycle并通过以下方式呈现结果依赖图 http://www.ndepend.com/docs/visual-studio-dependency-graph and 依赖矩阵 http://www.ndepend.com/docs/dependency-structure-matrix-dsm。我们有 400 多个命名空间,我们很高兴将它们全部正确地分层在十几个程序集中。依赖矩阵提供了一种方便的方法来一目了然地可视化分层命名空间结构。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)