.NET集合命名规范

18

我和我的同事一直在讨论应该如何称呼集合。

例如:

类 Product - 集合 - 类 Products

或者

类 Product - 集合 - 类 ProductCollection

我查看了一下是否有关于使用其中一种的指南或原因,但并没有发现明显的区别,框架好像都同时使用两种变体。我可以理解的争论是一个具有产品集合变量的类应该称为Products,但它的类型应该是ProductCollection。

哪个是正确的(如果有的话)?

在同样的情况下,是否有一种标准来命名函数的返回变量,例如retVal?

我们主要使用C#编程,尽管我不确定这是否影响我的问题。

5个回答

45

使用泛型时,很少有理由创建自定义集合类型。但如果你必须这样做,我会说ProductCollection最符合框架的命名约定。

不过,考虑使用List<Product>Collection<Product>,更好的选择是IList<Product>ICollection<Product>

编辑:这是对MrEdmundo下面评论的回应。

在您的情况下,您有两种选择。 最明显的选择是使用继承,如下所示:

class Ball { }

class BallCollection : List<Ball>
{
    public String Color { get; set; }
    public String Material { get; set; }
}

我之所以说这是显而易见的,是因为一开始看起来似乎是最好的想法,但经过一番思考后,很明显这不是最佳选择。如果你或微软创建了一个新的SuperAwesomeList<T>,并且希望使用它来改进BallCollection类的性能呢?这将很困难,因为你通过继承与List<T>类绑定在一起,改变基类可能会破坏任何将BallCollection作为List<T>使用的代码。

那么什么是更好的解决方案呢?在这种情况下,我建议您优先考虑组合而非继承。那么基于组合的解决方案会是什么样子呢?

class Ball { }

class BallCollection
{
    public String Color { get; set; }
    public String Material { get; set; }
    public IList<Ball> Balls { get; set; }
}

请注意,我已经声明了Balls属性的类型为IList<T>。这意味着您可以自由地使用任何类型来实现该属性,只要该类型实现了IList<T>接口。这意味着您随时可以自由地使用SuperAwesomeList<T>,从而使得该类型更加可扩展且更易于维护。


1
完全同意以上所有观点。如果您必须这么做,请将其命名为 XxxCollection。但是,如果可以避免的话最好不要这样做。 - David M
4
@MrEdmundo:啊哈,我明白了。那么在这种情况下,我会使用ProductCollection。但是要注意一点:通过组合的方式解决问题是否更好?换句话说,如果它包含一个List<Product>而不是从它继承,那么管理/扩展您的类型可能会更容易。 - Andrew Hare
好的。这不是我正在使用的,但似乎很有道理。想象一下我有一个袋子,里面装着球。这个袋子有颜色和材质(字符串)属性。我想我知道你要说什么了。这是关于袋子“是”一组球,还是袋子里的球只是袋子的属性的决定吗? - MrEdmundo
抱歉,我觉得我可能解释得不太好。颜色和材料是指包的颜色和材质。例如:尼龙制成的蓝色包包含球。 - MrEdmundo
1
当我更深入地思考时,也许我会让 Bag 实现 IEnumerable<Toy> 并使 Contents 属性成为 IList<Toy>(或将 Toy 与 Ball 交换)。不过我并不是专家 :p - Svish
显示剩余8条评论

23

Products 在我看来肯定是不正确的。一个非静态类名应该代表一个名词(而不是复数形式),因为你应该能够说“x是一个[classname]”。

显然,Products 不符合这个规则。而 ProductCollection 则符合:

举例说明:

var products = new Products(); // products is a Products

var products = new ProductCollection(); // products is a ProductCollection
哪一个听起来"对"?
关于集合类的命名:我通常尝试以这样的方式命名集合类,使得它很清楚它是什么类型的集合。
例如:
- class ProductCollection:只能枚举并检索 Count(即只实现 ICollection 接口)。 - class ProductList:可以使用 Add()、Insert() 等方法操作的列表(即实现 IList 接口)。 - class ProductDictionary:由某个键访问的产品字典(即实现 IDictionary 接口)。
如果存在疑问,最后一个可能会不明确字典的键是什么,因此最好指定键类型(例如 ProductDictionaryByString)。但是说实话,我很少这样命名它,因为大多数情况下键都会是字符串。

在这些示例中,使用products而不是list作为变量名会更好,不是吗? - Svish
当然,说得好。在实际的代码中,这样做会更好,但这只是为什么类应该以某种方式命名的示例。 - Philippe Leybaert

6
.NET Framework经常在其集合类型中使用“Collection”后缀。例如StringCollection、ObservableCollection、KeyedCollection等。因此,可以使用ProductCollection。

5

注意到没有人回答你关于 retVal 的问题(或者我可能只是变瞎了)。虽然我不是专家,但在 retVal 问题上,如果你的意思是像这样命名返回变量之类的东西,我并不100%确定你的意思,但是:

public void GetSomething(out object retVal) 
{
    retVal = ThingFactory.CreateSomething();
}

我会说,不管惯例是什么,都不要这样做。这很烦人。只需返回值即可。如果需要返回多个内容,则我认为该方法执行了多个操作(一个方法不应该如此),或者这些操作应该被包装在某种逻辑类中,以便返回。
如果你所说的“返回变量的命名”是指以下内容:
var retVal = ThingFactory.CreateSomething();

我会建议根据变量代表的对象来命名变量,以及它将要用于什么目的。如果是一组汽车的列表,则称其为listOfCars;如果是一块待食用的面包,则称其为pieceOfBreadpieceOfBreadToBeEatenLater

希望这能有所帮助,而且不会太离题 :p


2

Thesaurus.com

不用再纠结复数化的问题了。只需将以下保护符之一加到你的对象名字后:

  • Jumble(混杂)
  • Gob(一大块)
  • Trove(宝库)
  • Miscellany(杂集)
  • Vocab(词汇表)
  • Load(负载)
  • Agglomeration(聚集体)
  • Mound(堆)
  • Series(系列)
  • Lexicon(词典)
  • Muster(集合)
  • Glossary(术语表)
  • Hoard(囤积)
  • Swarm(群)
  • Group(组)
  • Cluster(簇)
  • Convoy(护航队)
  • Assemblage(聚集)
  • Herd(兽群)
  • Mob(暴民)
  • Batch(批次)
  • Amassment(积累)
  • Pile(堆)
  • Bank(库)
  • Congregation(集会)
  • Clump(丛)
  • Volume(卷)
  • Set(集)
  • Reserve(储备)
  • Compilation(编纂)
  • Flock(群)
  • Army(军队)

让它变得有趣。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接