-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Prerequisites
- Existing Issue: Search the existing issues for this repository. If there is an issue that fits your needs do not file a new one. Subscribe, react, or comment on that issue instead.
- Descriptive Title: Write the title for this issue as a short synopsis. If possible, provide context. For example, "Document new
Get-Foocmdlet" instead of "New cmdlet."
PowerShell Version
5.1, 7.2, 7.3, 7.4
Summary
For consistency in PowerShell, accessing the Count property should be encouraged as the preferred method to retrieve the number of elements in a collection, especially for scenarios in which it's unknown if zero, one or multiple objects are yielded.
Exceptions exist, but as a general rule of thumb, using Count provides a far more consistent experience in PS over Length.
Details
Countis widely available to PowerShell-noteworthy collection types and thus aids PowerShell's unified scalar/collection handling better.Lengthis, for the most part, limited to arrays.Array(and its derivatives) have both aCountandLengthproperty. In PS, there is no significant difference between using either.- However, the following notable collection types only have a
Count, not aLength.List<T>: A common general purpose collection type used by PS users and endorsed officially.$list = [Collections.Generic.List[object]]::new((1, 2, 3)) $list.Count # 3 # No Length, so member-access enumeration applies Length access to each element. $list.Length # 1, 1, 1
ArrayList: Used extensively throughout PS (remoting/job/mini-shell data marshalling,-ErrorVariable,-OutVariable,$Error, etc), albeit usage in new code is not recommended.Get-Item foo, bar, baz -ErrorAction SilentlyContinue -ErrorVariable errs $errs.Count # 3 $errs.Length # 1, 1, 1
Collection<T>: Used by the intrinsicForEach()/Where()methods and extensively in the[powershell]API.$collection = (1, 2, 3).ForEach{ $true } $collection.Count # 3 $collection.Length # 1, 1, 1
Lengthis particularly problematic with strings andFileInfo(both have a type-nativeLength) when a result could be one or multiple instances and typical pipeline semantics are in play.$result1 = 'foo', (, ('foo', 'bar')) | Get-Random $result.Length # Could be 2 or, unexpectedly in this context, 3 (length of the string) $result.Count # Could 1 or 2, as expected $result2 = Get-ChildItem -Path foo* -File $result2.Length # Could be 0, 2+ or, unexpectedly in this context, the size of a file $result2.Count # Could be 0, 1 or 2+, as expected # @(...) is a natural fit here, but is less likely to be considered by newer PS users.
Notes:
- PS does not intrinsicly make
Count/Lengthavailable to collections, hence the disparity between the two properties. Collections.IDictionary-implementing dictionaries are special-cased as scalar, so have a type-nativeCountand intrinsicLength. Types that only implement the generic version are treated as a collection, so have a type-nativeCountbut noLength. In both cases,Countrefers to the number of key/value pairs.- The argument of
CountvsLengthconcerns in-memory (fully collected) collections, not scenarios in which streaming is preferable.
Proposed Content Type
About Topic
Related Articles
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_intrinsic_members#properties
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_arrays#properties-of-arrays
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_properties#examples