When you return a collection from a PowerShell function, by default, PowerShell determines the data type of the return value as follows:
- If the collection has more than one item, the return result is an array. Note that the data type of the return result is System.Array , even if the returned object is a collection of another type.
- If the collection has one element, the result of the return is the value of this element, and not the collection of one element, and the data type of the return result is the data type of this element.
- If the collection is empty, the return result is $ null
$l_t = @() assigns an empty array to $ l_t .
$l_t2 = emptyArray sets $ null to $ l_t2 because the emptyArray function returns an empty collection, so the result of returning $ is zero .
$ l_t2 and $ l_t3 are zero, and they behave the same. Since you previously declared $ l_t as an empty array, adding either $ l_t2 or $ l_t3 to it , or using + = or the addToArray function, an element whose value is ** $ null * is added to the array.
If you want to force the function to save the data type of the returned collection object, use the comma operator:
PS> function emptyArray {,@()} PS> $l_t2 = emptyArray PS> $l_t2.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array PS> $l_t2.Count 0
Note. Empty parentheses after emtpyArray in the function declaration are redundant. You only need the brackets after the function name if you use them to declare parameters.
An interesting point is that the comma operator does not necessarily return the return value to the array.
Recall that, as I mentioned in the first paragraph, the default data type is the result of returning a collection with more than one System.Array element, regardless of the actual data type of the collection. For example:
PS> $list = New-Object -TypeName System.Collections.Generic.List[int] PS> $list.Add(1) PS> $list.Add(2) PS> $list.Count 2 PS> $list.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True List`1 System.Object
Note that the data type of this collection is List`1 , not System.Array .
However, if you return it from a function, inside the function the data type $ list will be List`1 , but it will be returned as a System .Array containing the same elements.
PS> function Get-List {$list = New-Object -TypeName System.Collections.Generic.List[int]; $list.Add(1); $list.Add(2); return $list} PS> $l = Get-List PS> $l.Count 2 PS> $l.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array
If you want the return result to be a collection of the same data type as the one in the returned function, the comma operator will do this:
PS> function Get-List {$list = New-Object -TypeName System.Collections.Generic.List[int]; $list.Add(1); $list.Add(2); return ,$list} PS> $l = Get-List PS> $l.Count 2 PS> $l.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True List`1 System.Object
This is not limited to massive collection objects. As far as I saw, at any time when PowerShell changes the data type of the returned object and you want the return value to keep the original data type of the object, you can do this before the object is returned with a comma, I first encountered this problem when writing a function. which requested the database and returned a DataTable. The return result was an hashtables array instead of a DataTable. Changing return $my_datatable_object to return ,$my_datatable_object made the function return the actual DataTable.