Powershell 分配给$null的对象属性未测试$null的true

Powershell 分配给$null的对象属性未测试$null的true,powershell,Powershell,我已经开始使用PowerShell完成一些事情,并在PowerShell中使用变量$null 我遇到了这样一个问题:当我将变量$null赋给类中定义的变量时,测试返回falsenottrue 示例代码: class test { [string]$test1 } $test = [test]::new() $test.test1 = $null $null -eq $test2 # tests true $null -eq $test.test1 # tests false 现

我已经开始使用PowerShell完成一些事情,并在PowerShell中使用变量
$null

我遇到了这样一个问题:当我将变量
$null
赋给类中定义的变量时,测试返回
false
not
true

示例代码:

class test {
    [string]$test1
}

$test = [test]::new()

$test.test1 = $null

$null -eq $test2 # tests true

$null -eq $test.test1 # tests false
现在,对未定义变量
$test2
的测试返回
true
,因为PowerShell中的每个未定义变量都被赋值
$null

但是如果我测试我分配给
$null
的对象
test
的属性
test1
,测试
$null
false

是因为在PowerShell中,
$null
是一个值为
$null
的对象,而现在该对象的属性不是
$null
,因为它将对象
$null
分配给它的值为空

我已经阅读了微软的文档,但它并没有启发我


如果我没有初始化变量,那么它将测试
true
$null

$test。test1
不是
$null
,它是空字符串(因为您明确地将它的值定义为
[string]
):

证明:

C:\> $test.test1 -eq ""
True

如果您使用的是
类型contstraint
[string]
[int]
Powershell会在
null
-赋值中使用默认的约束类型初始化成员

正如@robdy在上面的回答中所说的,您要么检查类型的默认值,要么删除约束

如果您使用的是
[int]
类型contstraint,这一点可能会更加明显:

class test {
    [int]$i1 = 42
}
    
$test = [test]::new()
Write-Host $test.i1
$test.i1 = $null
Write-Host $test.i1
    
输出:

42
0
详细说明:

  • 根据设计,
    [string]
    -PowerShell中的类型化变量、参数变量和自定义类属性不存储
    $null
    [1],只存储实际的字符串值赋值
    $null
    总是转换为
    '
    (空字符串)

    • 下面,
      $var
      接收
      '
      ,而不是
      $null
      ,原因是键入了
      [string]
      ;因此,第一个
      -eq
      测试失败,第二个测试成功

    • [string]$var=$null$null-等式$var;“”-等式$var

    • 请注意,其他.NET引用类型(与值类型相反,值类型基本上不能为null)在PowerShell中不受影响;也就是说,您可以为它们分配
      $null
      。值得注意的是,这也适用于
      [object]
      。请注意,约束变量/参数/属性的not type与键入变量/参数/属性相同

  • PowerShell
    类中未初始化的
    [string]
    属性当前默认值为
    $null
    应视为bug
    -请参阅

    • 如果显式初始化为
      $null
      ,这会再次转换为
      '
      ,并导致测试失败,则不一致性会变得明显

    • 类测试{[string]$test1=$null}$null-eq[test]::new().test1

    • 如果该错误已修复,并且您确实需要
      [string]
      类型的属性中的
      $null
      值-这在PowerShell代码的上下文中是不明智的-您必须使用
      [NullString]::value
      ,如下面链接的答案所示:
      类测试{[string]$test1=[NullString]::Value}$null-eq[test]::new().test1

有关详细信息,请参阅



[1] 无法存储
$null
是PowerShell为了简化而施加的限制。底层的.NET类型在其他语言中通常没有这种限制,尤其是在C语言中。

这是引起我注意的一件事。但我认为会是这样的,因为您没有初始化变量,因此它没有类型约束或任何形式的
$null
。如以下示例所示:
类测试{[string]$test1}$test=[test]::new()$test.test1$null-eq$test2#tests true$null-eq$test.test1#tests true$test.test1 | gm#返回时出现错误“gm:您必须为Get-Member cmdlet指定一个对象”
@toudumbtocode,我希望他们能解决这一不一致的问题。请注意,在参数变量中,与在常规变量中一样,缺少初始化也会导致
'
;e、 例如,
和{param([string]$test1)$null-eq$test1}
产生
$false
。如果不一致性被消除,并且您确实需要一个
$null
值-这在PowerShell代码的上下文中是不明智的-您必须使用
[NullString]::value
,如链接的答案所示:
类测试{[string]$test1=[NullString]::value}$null-eq[test]::new()。test1
42
0