Collection type name does not end in Collection or Dictionary
ID |
vbnet.maintainability.collection_suffix |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
medium |
Remediation Effort |
low |
Resource |
Naming |
Language |
VB.NET |
Description
Reports a type that is a collection - it implements ICollection, IList, ISet, IDictionary or one of their generic or read-only variants, or derives from a collection base class such as CollectionBase, Collection(Of T), ReadOnlyCollection(Of T) or KeyedCollection(Of ,) - whose own name does not end in one of the suffixes the convention allows: Collection, Dictionary, List, Set, Stack, Queue or Map. Generic types are judged on their own name and not on their type parameters, so Pallet(Of TItem) is reported while PalletCollection(Of TItem) is not. Types that merely implement IEnumerable, which is also how iterators are written, are not reported. This is a convention rule and is reported at informational severity.
Rationale
A collection is used differently from every other kind of object: it is enumerated in a For Each, indexed, counted, passed where a sequence is expected, and - the part that bites - it is the one type where returning Nothing instead of an empty instance breaks callers, and where exposing a mutable instance through a property hands out the ability to change your state. All of that follows from the type being a collection, and the suffix is what makes it visible at the places where those decisions are taken: a signature such as Function Load() As Bins gives no indication that the result can be enumerated or that it might come back empty, whereas As BinCollection does. The suffix also carries the difference between the collection and its element, which is the ambiguity plural names cannot resolve: Boxes could be a collection of boxes or a single crate holding boxes, while BoxCollection cannot be misread, and a BoxCollection sitting next to a Box in the same namespace documents the relationship without a comment. Because the type name appears in every signature that produces or consumes the collection, renaming later is a wide change.
The following code illustrates the pattern detected by this rule:
Namespace Warehouse
' BAD: implements ICollection but the name does not say it is a collection.
' FLAGGED: Collection type name does not end in Collection or Dictionary
Public Class Bins
Implements System.Collections.ICollection
Public ReadOnly Property Count As Integer Implements ICollection.Count
Get
Return 0
End Get
End Property
End Class
Remediation
Rename the type so that it ends in the suffix that matches what it is: Collection for a general collection, so Bins becomes BinCollection and Pallet(Of TItem) becomes PalletCollection(Of TItem); Dictionary for a keyed collection implementing IDictionary; List, Set, Stack or Queue when the type really is one of those and the name would be misleading otherwise. Name the collection after its element in the singular rather than pluralizing - BinCollection, not BinsCollection - since the suffix already carries the plurality. If the type is not really a collection and only happens to implement one of these interfaces, prefer holding a collection in a property instead of implementing the interface, so the name and the contract agree. Use the rename refactoring in the IDE so that every signature and instantiation is updated in the same step.