Why and how are these two $null values different?

前端 未结 3 1540
天涯浪人
天涯浪人 2020-11-30 14:20

Apparently, in PowerShell (ver. 3) not all $null\'s are the same:

    >function emptyArray() { @() }
    >$l_t = @() ; $l_t.Count
0
    &g         


        
3条回答
  •  醉梦人生
    2020-11-30 14:22

    In particular, is $l_t2 really $null or not?

    $l_t2 is not $null, but a [System.Management.Automation.Internal.AutomationNull]::Value. It is a special instance of PSObject. It is returned when a pipeline returns zero objects. That is how you can check it:

    $a=&{} #shortest, I know, pipeline, that returns zero objects
    $b=[System.Management.Automation.Internal.AutomationNull]::Value
    
    $ReferenceEquals=[Object].GetMethod('ReferenceEquals')
    
    $ReferenceEquals.Invoke($null,($a,$null)) #returns False
    $ReferenceEquals.Invoke($null,($a,$b))    #returns True
    

    I call ReferenceEquals thru Reflection to prevent conversion from AutomationNull to $null by PowerShell.

    $l_t1 -eq $null returns nothing

    For me it returns an empty array, as I expect from it.

    $l_t2.count returns 0

    It is a new feature of PowerShell v3:

    You can now use Count or Length on any object, even if it didn’t have the property. If the object didn’t have a Count or Length property, it will will return 1 (or 0 for $null). Objects that have Count or Length properties will continue to work as they always have.

    PS> $a = 42 
    PS> $a.Count 
    1
    

     

    And why does $l_t2 suddenly seem to become "more $null" when it gets passed in the the function addToArray as a parameter???????

    It seems that PowerShell converts AutomationNull to $null in some cases, like calling .NET methods. In PowerShell v2, even when saving AutomationNull to a variable it gets converted to $null.

提交回复
热议问题