这两个$ null值为何以及如何不同? [英] Why and how are these two $null values different?
问题描述
显然,在PowerShell(版本3)中,并非所有$null
都相同:
Apparently, in PowerShell (ver. 3) not all $null
's are the same:
>function emptyArray() { @() }
>$l_t = @() ; $l_t.Count
0
>$l_t1 = @(); $l_t1 -eq $null; $l_t1.count; $l_t1.gettype()
0
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
>$l_t += $l_t1; $l_t.Count
0
>$l_t += emptyArray; $l_t.Count
0
>$l_t2 = emptyArray; $l_t2 -eq $null; $l_t2.Count; $l_t2.gettype()
True
0
You cannot call a method on a null-valued expression.
At line:1 char:38
+ $l_t2 = emptyArray; $l_t2 -eq $null; $l_t2.Count; $l_t2.gettype()
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
>$l_t += $l_t2; $l_t.Count
0
>$l_t3 = $null; $l_t3 -eq $null;$l_t3.gettype()
True
You cannot call a method on a null-valued expression.
At line:1 char:32
+ $l_t3 = $null; $l_t3 -eq $null;$l_t3.gettype()
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
>$l_t += $l_t3; $l_t.count
1
>function addToArray($l_a, $l_b) { $l_a += $l_b; $l_a.count }
>$l_t = @(); $l_t.Count
0
>addToArray $l_t $l_t1
0
>addToArray $l_t $l_t2
1
那么$l_t2
与$l_t3
有何不同?为什么?特别是$l_t2
真的是$null
吗?请注意,$l_t2
不是一个空数组($l_t1
是一个空数组,而$l_t1 -eq $null
如预期那样不返回任何内容),但它也不是真正的$null
,就像$l_t3
一样.特别地,$l_t2.count
返回0而不是错误,此外,将$l_t2
添加到$l_t
的行为就像添加一个空数组,而不是添加$null
一样.为什么$l_t2
在函数addToArray
中作为参数传递时突然变成更多$null
" ????
So how and why is $l_t2
different from $l_t3
? In particular, is $l_t2
really $null
or not? Note that $l_t2
is NOT an empty array ($l_t1
is, and $l_t1 -eq $null
returns nothing, as expected), but neither is it truly $null
, like $l_t3
. In particular, $l_t2.count
returns 0 rather than an error, and furthermore, adding $l_t2
to $l_t
behaves like adding an empty array, not like adding $null
. And why does $l_t2
suddenly seem to become "more $null
" when it gets passed in the the function addToArray
as a parameter???????
任何人都可以解释这种行为,或者将我指向可以解释这种行为的文档吗?
Can anyone explain this behaviour, or point me to documentation that would explain it?
下面的PetSerAl的答案是正确的. 我还在以下位置找到了这个stackOverflow帖子同样的问题.
The answer by PetSerAl below is correct. I have also found this stackOverflow post on the same issue.
Powershell版本信息:
Powershell version info:
>$PSVersionTable
Name Value
---- -----
WSManStackVersion 3.0
PSCompatibleVersions {1.0, 2.0, 3.0}
SerializationVersion 1.1.0.1
BuildVersion 6.2.9200.16481
PSVersion 3.0
CLRVersion 4.0.30319.1026
PSRemotingProtocolVersion 2.2
推荐答案
尤其是
$l_t2
真的是$null
吗?
$l_t2
不是$null
,而是[System.Management.Automation.Internal.AutomationNull]::Value
.它是PSObject
的特殊实例.当管道返回零个对象时,将返回它.这就是您可以检查的方式:
$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
我通过反射调用ReferenceEquals
,以防止PowerShell将AutomationNull
转换为$ null.
I call ReferenceEquals
thru Reflection to prevent conversion from AutomationNull
to $null by PowerShell.
$l_t1 -eq $null
不返回任何内容
对我来说,它返回一个空数组,正如我期望的那样.
For me it returns an empty array, as I expect from it.
$l_t2.count
返回0
这是PowerShell v3的新功能:
It is a new feature of PowerShell v3:
您现在可以在任何对象上使用计数"或长度",即使该对象没有该属性.如果对象没有Count或Length属性,它将返回1(或$ null为0).具有Count或Length属性的对象将像往常一样继续工作.
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
$l_t2
为什么在将$l_t2
作为参数传递给函数addToArray
时突然变成更多$null
"?
And why does
$l_t2
suddenly seem to become "more$null
" when it gets passed in the the functionaddToArray
as a parameter???????
在某些情况下,PowerShell似乎会将AutomationNull
转换为$null
,例如调用.NET方法.在PowerShell v2中,即使将AutomationNull
保存到变量中,它也会转换为$null
.
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
.
这篇关于这两个$ null值为何以及如何不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!