在 C# 中防止 helper 类 命名污染的推荐方法?

Recommended way to prevent naming pollution by helper classes in C#?

我经常遇到这样的模式,即我有一个主 class 和几个较小的助手 class es 或结构。

我希望这些结构的名称尽可能简洁。因此,当我有一个名为 CarFinder 的 class 大量使用一些仅(或主要)在内部使用的特殊密钥 object 时,我想称其为 object Key 而不是 CarFinderKey

一切都删除了所有额外的 fuzz,当我在阅读它时试图理解 class 时会分散我的注意力。

当然,我不想用一个名为 Key 的小帮手 class 污染其余代码 - 它很可能会发生冲突和混淆。

在一个完美的世界中,我希望有一个像 internal to this namespace 这样的关键字,但由于它不存在,所以我可以想到以下选项:


  1. 使用 internal 并将 class 放在不同的项目中。

优点:完美封装

缺点:大量的组织开销和不必要的复杂依赖关系。

注意:我说的不是真正的大型独立系统,它们无疑值得自己组装。


  1. 将其放在不同的 child 命名空间中,例如 CarFinding.Internal

优点:易于实现

缺点:不小心导入命名空间时仍然会造成污染


  1. 将助手 class 作为 child class 放入 CarFinder.

优势 内部不污染,甚至可以提升为public helper struct,暴露于外界CarFinder.Key

缺点 必须将助手 class 放在同一个文件中,或者将其封装在外部文件中并用 public partial class 围绕它。第一个使文件变得不必要的长,第二个感觉真的很丑。


  1. 随便叫吧CarFinderKey

优点易于实施。

缺点 在我看来增加了太多 fuzzCarFinder。仍然不必要污染命名,只是用一个不太可能冲突的名字。


推荐的指南是什么?

我会把 class 和它们的 "helpers" 放在它们自己的命名空间中 MyNamespace.CarFinding,

所以你有:

  • MyNamespace.CarFinding.CarFinder

  • MyNamespace.CarFinding.Key

我会把这个命名空间放在项目的子文件夹中。

这不会阻止内部助手 class 在项目的其他地方使用,但您可以从父名称空间引用您的助手 CarFinding.Key

就个人而言,我不介意 CarFinderKey 造成的额外 "fuzz",原因如下:曾经在一个非常大的项目上工作,我们试图使用名称空间来消除名称歧义。

因此,当您扩展系统时,您很容易在代码编辑器中打开 10 个选项卡,所有选项卡都命名为 "Key.cs"。那真的不好玩。

这是基于意见的。无论如何,我会:

  1. 尝试使其成为 CarFinder 的私有嵌套 class,这通常会失败,因为 Key 需要传递给 CarManager , 你知道我的意思。 Public 不鼓励嵌套 class。

  2. 我会将其放入名为 Core 的子命名空间中,这是内部内容的通用名称。对我来说,Core 按照命名约定是 "namespace internal"。

  3. 项目越大,名称越长。 CarFinderKey 仍然是一个有效的选项。

我永远不会为此创建额外的程序集。就是感觉不对。

我多次遇到同样的困境,个人使用(3)和(4)的变体。

(3):我既不将嵌套的 class/struct 放在同一个文件中(如果它很小并且确实与父 class 相关),也不使用单独的文件在 partial ParentClass 声明中——唯一的缺点是它多了一层缩进,但我可以接受。我对违反 FxCop 规则或其他建议也没有问题——毕竟,它们只是建议,而不是强制性的。但是很多人确实对所有这些或其中的一些有问题,所以让我们继续吧。

(4):您已经描述了缺点。我要分享的是我是如何克服它们的。同样,它是个人的,可能喜欢也可能不喜欢,但就是这样。

首先,假设我们为密钥 class 使用一个单独的文件,并将 class 命名为 CarFinderKey

然后, CarFinder class 的代码文件中,我们将以下行放在 的末尾(或内部的任何位置)using 部分:

using Key = CarFinderKey;

这样,只在CarFinderclass代码文件里面,任何需要CarFinderKey的地方,我们可以简单的引用一下作为 Key,目标是什么。同时我们保留了所有的优势,没有冲突。智能工作 w/o 任何问题。在 VS2015 中,灯泡甚至会在文件中找到 CarFinderKey 的任何地方为您建议 "simplify the name"。

您的决定应取决于您的设计。你的钥匙 class 真的只是 CarFinder 的钥匙,还是也可以用来找摩托车或房子什么的。

著名的四人帮制定的第一个规则是 "Design for change"。如果你真的认为在不久的将来你的钥匙也可以用来找房子或摩托车,那么把你的钥匙 class 设为私有以致其他人无法使用它并不是一个好主意。

既然你说的是私人助手 classes,我想你的钥匙只对 CarFinders 有用。

如果是这种情况,并且您的设计规定密钥仅对 CarFinders 有用,或者甚至:如果它的设计甚至在 CarFinders 之外也没有用,那么密钥 class 应该成为 CarFinders class 的一部分。将此与您将在 CarFinders class 中使用的简单整数进行比较,您会在 CarFinders class 中将其声明为私有,不是吗?

给您留下一个大文件或部分定义的问题。从设计的角度来看没有区别。对于编译器也没有区别。唯一的区别在于必须阅读它的人。如果您认为 class 的用户很少需要阅读您的密钥 class 的定义,那么最好将其定义在一个单独的文件中。但是,如果您在阅读 CarFinder class 时经常需要阅读密钥 class,您应该尽可能轻松地访问密钥 class。如果您的开发环境是完全面向文件而不是面向 class,那么我认为在那种情况下,大文件的缺点小于必须在文件之间切换的缺点。