组合哈希表时PowerShell的行为
问题 为什么组合哈希表时PowerShell的行为,powershell,null,hashtable,powershell-5.0,Powershell,Null,Hashtable,Powershell 5.0,问题 为什么$null+@{}有效,而@{}+$null无效;即使null被强制转换为哈希表(@{}+([hashtable]$null)) 示例代码 [hashtable]$a = @{demo1=1;demo2='two'} [hashtable]$b = @{demo3=3;demo4='Ivy'} [hashtable]$c = $null #combining 2 hashtables creates 1 with both hashes properties (would er
$null+@{}
有效,而@{}+$null
无效;即使null被强制转换为哈希表(@{}+([hashtable]$null)
)
示例代码
[hashtable]$a = @{demo1=1;demo2='two'}
[hashtable]$b = @{demo3=3;demo4='Ivy'}
[hashtable]$c = $null
#combining 2 hashtables creates 1 with both hashes properties (would error if any properties were common to both)
write-verbose 'a + b' -Verbose
($a + $b)
#combining a null hashtable with a non-null hashtable works
write-verbose 'c + a' -Verbose
($c + $a)
#combing 2 null hashtables is fine; even if we've not explicitly cast null as a hashtable
write-verbose 'c + null' -Verbose
($c + $null)
#however, combinging a hashtable with null (i.e. same as second test, only putting null as the right argument instead of the left, produces an error
write-verbose 'a + c' -Verbose
($a + $c)
输出
Name Value
---- -----
demo3 3
demo4 Ivy
demo1 1
demo2 two
VERBOSE: c + a
demo1 1
demo2 two
VERBOSE: c + d
VERBOSE: a + c
A hash table can only be added to another hash table.
At line:19 char:1
+ ($a + $c)
+ ~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : AddHashTableToNonHashTable
旁注
[hashtable]$a = @{demo1=1;demo2='two'}
[hashtable]$b = @{demo3=3;demo4='Ivy'}
[hashtable]$c = $null
#combining 2 hashtables creates 1 with both hashes properties (would error if any properties were common to both)
write-verbose 'a + b' -Verbose
($a + $b)
#combining a null hashtable with a non-null hashtable works
write-verbose 'c + a' -Verbose
($c + $a)
#combing 2 null hashtables is fine; even if we've not explicitly cast null as a hashtable
write-verbose 'c + null' -Verbose
($c + $null)
#however, combinging a hashtable with null (i.e. same as second test, only putting null as the right argument instead of the left, produces an error
write-verbose 'a + c' -Verbose
($a + $c)
顺便说一句,这让我发现了哈希表空合并操作的一个有用技巧:
($c+@{})
。e、 g.($a+($c++{}))
避免了上面产生的错误/($a++{})+($c++}))
为我们提供了一种完全安全的方法来添加哈希表,其中任何一个值都可能为空。我试图找出确切的原因,但我不能确定
我最初的信念是:
- 可能会发生某些PowerShell隐式类型强制,其中右侧的内容被强制转换为与左侧的类型匹配。e、 g.使用
时,右侧的1变成字符串,输出为“1”+1
,但“11”
右侧变成数字,输出为1+“1”
。2
- 这肯定不会发生,或者
会抛出强制转换错误,或者强制转换并执行null+null=null,而不会像它那样输出空哈希表$null+@{}
- 这肯定不会发生,或者
- 对数字以外的事物添加A+B有一些基本规则,如数组连接,但除此之外,它将落在下面的.Net框架中,并尝试执行方法调用,如
当您尝试将右侧的内容添加到左侧时,将由左侧的内容决定会发生什么。A.op_Addition(B)
- 这确实发生了,但在这里没有发生。考虑<代码> @ {}+0 告诉您只能将一个哈希表添加到一个哈希表中。(如果是,则可以将其添加到null)。并且
告诉您哈希表不包含0+@{}
方法。因此,null的加法似乎应该给出这个错误,但是没有,因为它没有回到这个机制op_Addition
- 这确实发生了,但在这里没有发生。考虑<代码> @ {}+0 告诉您只能将一个哈希表添加到一个哈希表中。(如果是,则可以将其添加到null)。并且
PSv3语言规范(我认为这是最新的可用版本)在此处下载:,其中提到了附加内容: 7.7.1加法说明:加法运算符+的结果是两个操作数在通常运算后指定的值之和 已应用算术转换(§6.15) 通常的算术转换表示: 如果两个操作数均未指定数值类型的值,则[…]所有指定值$null的操作数将转换为int类型的零,并且该过程将继续进行下面列出的数值转换 这意味着在两个示例中$null都转换为0。虽然这不可能发生,因为
0+@{}
和@{}+0
都是错误
第7.7节中明确提到添加两个哈希表:
7.7.4哈希表串联说明:当两个操作数都指定哈希表时,二进制+运算符将创建一个新的哈希表
包含由后面的左操作数指定的元素的
由右操作数指定的元素立即执行
好的,哈希表的添加由PowerShell引擎处理,但只添加两个哈希表
第7节。导言说:
Windows PowerShell:如果PowerShell未定义操作,将检查左操作数指定的值类型,以查看其是否具有相应的op_uu方法
从规范中可以看出,PowerShell似乎没有定义$null+哈希表操作,+
的对应方法是op\u Addition
——哈希表没有的方法,请参见前面的错误代码——这并没有引发错误,不仅如此,如果加0,错误来自右操作数,而不是左操作数
规范中另一个有趣的部分是:
4.1.2未指定空类型的特征
因此,总结似乎是:
-正在触发PowerShell处理添加两个哈希表,即使规范没有说它会这样做@{}+$null
-看起来有一个隐式的$null+@{}
规则,尽管规范似乎没有提到它,而且它可能依赖于实现$null+x=x
-将$null强制转换为数字类型将导致0(6.15算术转换),但将其强制转换为任何其他(?)似乎会导致$null(不在规范中)[]$null
- 注释和链接链表示,
没有类型,这与PowerShell规范4.1.2“null类型”相抵触,后者表示“null类型有一个实例,即自动变量$null(§2.3.2.2),也称为null值。此类型的特征未指定。”因此,至少在术语上,它在PowerShell中被描述为一个类型,即使您无法在其上获取type()李>$null
([hashtable]$null)-eq$null
为真$null+@{}
有效,因为添加到$null.Ah没有限制;所以null是无类型的,即使是强制转换。多谢各位。有道理/奇怪的是,这不是我以前遇到过的情况。关于C#的相关回答: