@mjolinor answer is a simple and correct answer to the question (1). This answer actually leads to two more questions.
about_Comparison_Operators states the following:
When the input is a set of values, comparison operators return any corresponding values. If there are no matches in the collection, comparison operators return nothing.
This implies that the behavior depends on Powershell's definition of a “collection” in this context. The deployment of pipelines has a similar dependence on the definition of “collection”. This also implies that replacing the LHS and RHS comparison operators may have a significant difference.
So, in addition to the initial question 2, we have two more answers:
- How do you distinguish between
$null and an empty array? - What types of Powershell comparison operators are considered as a collection?
- Does exchanging LHS and RHS data change comparison operators?
These three remaining questions can be answered empirically using the script at the end of this answer.
Test results
CollectionType x_eq_Null coll_LHS_result Null_eq_x coll_RHS_result -------------- --------- --------------- --------- --------------- string False Boolean False Boolean ArrayList {} Object[] False Boolean Hashtable False Boolean False Boolean Queue {} Object[] False Boolean SortedList False Boolean False Boolean Stack {} Object[] False Boolean Dictionary False Boolean False Boolean List {} Object[] False Boolean Null True Boolean True Boolean boolean False Boolean False Boolean int32 False Boolean False Boolean char False Boolean False Boolean
We can use the table to answer questions:
- How do you distinguish between
$null and an empty array?
Moving the collection to the operator's RHS (for example, $null -eq @() ) results in a Boolean for all types tested (see column coll_RHS_result ). This means that $null -ne @() evaluates to True as expected, which allows us to reliably detect the difference between $null and @() .
- What types of Powershell comparison operators are considered as a collection?
Each of the types whose coll_LHS_result are Object[] .
- Does exchanging LHS and RHS data change comparison operators?
Of course. Setting a collection on an LHS operator gives an array as a result. Putting the scalar on the operator LHS, the result is a logical value.
Test script
('string', ('')), ('ArrayList', (New-Object System.Collections.ArrayList)), ('Hashtable', (New-Object System.Collections.Hashtable)), ('Queue', (New-Object System.Collections.Queue)), ('SortedList', (New-Object System.Collections.SortedList)), ('Stack', (New-Object System.Collections.Stack)), ('Dictionary', (New-Object "System.Collections.Generic.Dictionary``2[System.String,int32]")), ('List', (New-Object System.Collections.Generic.List``1[int32])), ('Null', ($null)), ('boolean', ($false)), ('int32', ([int32]0)), ('char', ([char]"`0")) | % { New-Object PSObject -Property @{ CollectionType = $_[0] x_eq_Null = $_[1] -eq $null coll_LHS_result = ($_[1] -eq $null).GetType().Name Null_eq_x = $null -eq $_[1] coll_RHS_result = ($null -eq $_[1]).GetType().Name } } | select CollectionType,x_eq_Null,coll_LHS_result,Null_eq_x,coll_RHS_result | ft -AutoSize