在Powershell中测试null:为什么测试空数组的行为与空字符串不同?

时间:2015-04-13 20:10:15

标签: arrays powershell types null

考虑这段代码

"Type: array"
$v = @()
"  -eq `$null: $($v -eq $null)"
"  -ne `$null: $($v -ne $null)"

"Type: string"
$v = ''
"  -eq `$null: $($v -eq $null)"
"  -ne `$null: $($v -ne $null)"

产生以下结果:

Type: array
  -eq $null: 
  -ne $null: 
Type: string
  -eq $null: False
  -ne $null: True
  1. 为什么-eq-ne的行为符合预期的空字符串,但对空数组求值为null或为空?

  2. 更重要的是,您如何区分$null和空数组?

2 个答案:

答案 0 :(得分:6)

当比较运算符用于集合时,它们不返回布尔值($ true或$ false)。它们返回满足条件的集合的所有成员。

请参阅:

Get-help About_Comparison_Operators

答案 1 :(得分:2)

@ mjolinor answer是问题(1)的简单而正确的答案。这个答案实际上会导致另外两个问题。

about_Comparison_Operators声明如下:

  

当输入是值的集合时,   比较运算符返回任何匹配值。如果没有比赛   在集合中,比较运算符不会返回任何内容。

这意味着行为取决于Powershell对"集合"的定义。在这种背景下。 Pipeline unrolling has a similar dependence on the definition of "collection".这也意味着交换比较运算符的LHS和RHS可能会产生重大差异。

因此,除了最初的问题2之外,我们还有两个未回答的问题:

  1. 如何区分$null和空数组?
  2. Powershell比较运营商将哪些类型视为集合?
  3. 交换比较运算符的LHS和RHS会产生影响吗?
  4. 这三个剩下的问题都可以使用本答案末尾的脚本凭经验回答。

    测试结果

    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        
    

    我们可以使用该表来回答问题:

      
        
    1. 如何区分$null和空数组?
    2.   

    将集合移动到运算符的RHS(例如$null -eq @())会为所有测试类型生成一个布尔值(请参阅列coll_RHS_result)。这意味着$null -ne @()按预期评估为True,这使我们能够可靠地检测$null@()之间的差异。

      
        
    1. Powershell比较运营商将哪些类型视为集合?
    2.   

    coll_LHS_resultObject[]的每种类型。

      
        
    1. 交换比较运算符的LHS和RHS会产生影响吗?
    2.   

    确实如此。将集合放在运算符的LHS上会产生一个数组。将标量放在运算符的LHS上会产生一个布尔值。

    测试脚本

    ('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