它是通过其字符串表示来测试空(无属性)自定义对象([pscustomobject])的最简单解决方案 ,但是你需要使用一个可扩展的字符串(字符串插值,"...")而不是.ToString()来获得它:
# Returns $True, if custom object $test is empty, i.e. has no properties
-not "$test"
注意:-not $test.ToString()应该是等价的,但目前(从 PowerShell Core 6.1 开始)不是,因为bug。由于存在错误,any [pscustomobject] 实例返回 空字符串 from.ToString()。
另一种解决方法是使用.psobject.ToString()。
只有一个空(无属性)自定义对象字符串化为可扩展字符串内的 空字符串,并且在 PowerShell 中将一个空字符串强制转换为布尔值会产生 $False,而任何非空字符串都会产生$True.
另一种方法是与空字符串进行比较作为 LHS,这会隐式强制 RHS 上的 [pscustomobject] 被字符串化:
# NOTE: Works ONLY with '' on the LHS.
'' -eq $test
概念上更清晰的方法,虽然它依赖于隐藏的.psobject 属性 PowerShell 添加到所有对象,包含反射信息:
0 -eq @($test.psobject.Properties).Count
请注意需要使用@(...) 来强制枚举属性,以便对其进行计数 - 请参阅下一节。
上述方法很方便,但如果$test 是一个具有许多属性的大型对象,它可能会很昂贵——尽管从绝对意义上讲,这在实践中可能并不重要。
一个更便宜但更模糊的解决方案是访问.psobject.Properties集合而不枚举其所有成员:
# Returns $true, if $test has no properties
-not $test.psobject.Properties.GetEnumerator().MoveNext()
.psobject.Properties 集合显然是惰性枚举的,因此没有 .Count 属性;因此,使用 .GetEnumerator().MoveNext() 是一种将枚举限制在 first 属性(如果有)的方法。
至于你尝试了什么:
$test -eq $null
$test 仍然是一个对象,即使它碰巧没有属性,而且根据定义,一个对象绝不是$null。
-not $test
PowerShell 的隐式到布尔转换将 any [pscustomobject] 实例视为$True,无论它是否恰好具有属性;例如,[bool] ([pscustomobject] @{}) 产生 $True。
要了解如何将其他数据类型强制转换为布尔值,请参阅this answer。