2

class在 powershell 脚本中使用关键字。

我想序列化我的自定义类的实例,但我观察到$null成员被序列化为""而不是null.

再生产:

Class foo{
    [string]$X
}

[foo]@{ x = $null } | ConvertTo-Json

$foo = New-Object foo
$foo.X = $null

$foo | ConvertTo-Json

输出:

{
    "X":  ""
}
{
    "X":  ""
}

但我期待:

{
    "X":  null
}
{
    "X":  null
}

作为旁注,这有效:

@{ X = $null } | ConvertTo-Json

它输出预期:

{
    "X":  null
}

有没有办法来解决这个问题 ?

PS:如果重要$PSVersionTable输出:

Name                           Value                                                                                                                                                                     
----                           -----                                                                                                                                                                     
PSVersion                      5.1.19041.546                                                                                                                                                             
PSEdition                      Desktop                                                                                                                                                                   
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                                                   
BuildVersion                   10.0.19041.546                                                                                                                                                            
CLRVersion                     4.0.30319.42000                                                                                                                                                           
WSManStackVersion              3.0                                                                                                                                                                       
PSRemotingProtocolVersion      2.3                                                                                                                                                                       
SerializationVersion           1.1.0.1                                                                                                                                                                   
4

2 回答 2

3

有没有办法来解决这个问题 ?

解决方法取决于您对输入的控制级别,但无法$null直接分配给[string]-typed PowerShell 类属性)

PowerShell 类中的运行时类型强制执行不依赖于 .NET 的隐式类型转换规则 - 这被卸载到 PowerShell 的现有语言基础结构和在那里找到的转换逻辑,并且默认类型转换器[string] 始终返回一个实例,从不为空。

键入变量时,您可以观察到相同的行为:

Remove-Variable X -Force

# Let's assign $null to a variable with no type constraints
$X = $null
# True - we can assign $null to a variable without type constraints just fine
$null -eq $X

# Let's apply a type constraint and assign `$null` again
[string]$X = $null
# False - actual value assigned after type constraint applied is not $null anymore
$null -eq $X
# True - PowerShell has converted $null to ''
'' -eq $X

因此,如果您希望它保留值,则必须输入$X字符串以外的其他内容([object]例如)$null

于 2020-10-21T14:04:27.777 回答
2

Mathias R. Jessen 的有用答案很好地解释了这个问题:如果你分配$null给一个[string]类型化的属性或变量,你最终会得到''(空字符串)。

有一个 -obscure- workaround,它假设您可以控制您分配的值:

您可以分配[NullString]::Value[string]-type-constrained 变量或属性以使其存储$null值:

Class foo {
  # Default to $null
  [string] $X = [NullString]::Value
}

[foo]::new() | ConvertTo-Json

[foo] @{ X = [NullString]::Value } | ConvertTo-Json

($o = New-Object foo).X = [NullString]::Value
$o | ConvertTo-Json

笔记:

  • 的主要目的[NullString]::Value是允许将 true null( $null) 值传递给.NET Methodsstring的类型化参数,这在传递[string]类型化 PowerShell 变量或属性时不起作用,它们在赋值时总是转换$null''(空字符串),如在马蒂亚斯的回答。

  • 虽然您也可以在纯 PowerShell 代码中使用它,但如上所示,请注意其他接受[string]-typed 值的代码可能不会期望它们永远是$null,并且将值传递给另一个[string]-constrained (参数)变量再次转换为''.

  • 有关更多信息,请参阅此答案

上述产量:

{
  "X": null
}
{
  "X": null
}
{
  "X": null
}
于 2020-10-21T14:26:45.437 回答