我在 PowerShell ISE 和 VS Code 中尝试过这段代码,结果同样奇怪。没有断点,输出为 EMPTY
, 但在 "NULL"
的行中有一个断点,输出为 NULL
(如预期的那样)。为什么?
function demo {
param(
[string] $value = [NullString]::Value
)
if ($null -eq $value) {
"NULL"
} elseif ($value -eq '') {
"EMPTY"
} else {
"$value"
}
}
demo
我现在知道,当您将类型修饰符 [string] 用于参数时,PowerShell 将始终将非字符串值(例如 $null 或 [NullString]::Value)转换为(空)字符串。
好吧,我可以忍受,但如果在这种情况下调试很奇怪,你自己很难弄清楚。
最佳答案
PetSerAl和以前一样,在对该问题的评论中提供了关键指针:
一个 known optimization bug是最可能的原因 (从 Windows PowerShell v5.1/PowerShell Core v6.1.0 开始),当代码在 Visual Studio Code 或 ISE 调试器中运行时,该错误恰好被掩盖了。
因此,您可以使用相同的 解决方法 在链接的错误报告中提到:调用Remove-Variable
函数体中的任何位置(它的存在就足够了 - 实际上不需要在运行时进行调用):
function demo {
param(
[string] $value = [NullString]::Value
)
# Workaround for optimization bug
if ($False) { Remove-Variable }
if ($null -eq $value) {
"NULL"
} elseif ($value -eq '') {
"EMPTY"
} else {
"$value"
}
}
demo
现在你总是得到
"NULL"
作为输出,无论是否调试。但是,最好限制使用
[NullString]::Value
达到它的设计目的:通过 null
至string
.NET 方法的类型参数 - 见下文。至于为什么使用
[NullString]::Value
完全需要才能通过 $null
到字符串参数/存储$null
在 [string]
变量 ,假设 .NET 字符串通常可以存储 null
( $null
) 直接:通过(历史)设计,PowerShell 转换
$null
至''
(空字符串)当您将其分配给 [string]
多变的;这是理由:来自 https://github.com/PowerShell/PowerShell/issues/4616#issuecomment-323530442 :
The thinking behind the design was that in most ways,
$null
and the empty string both represent the same error condition and that in the rare case where a distinction was important,$PSBoundParameters
would be sufficient to distinguish between knowing a value was provided or not.
鉴于 even passing
$null
directly performs conversion to ''
when passing arguments to string
-typed .NET methods ,您无法通过 null
到 v2 的此类方法。为了解决这个问题,版本 3 引入了
[NullString]::Value
,它明确表示希望通过 $null
在字符串上下文中。(替代方案 - 使 PowerShell 字符串默认为
$null
并允许直接分配 $null
- 被认为是会破坏太多现有脚本的更改。)使用
[NullString]::Value
超出其预期目的 - 即传递 null
至string
.NET 方法中的参数 - 是有问题的,因为 PowerShell 不期望 [string]
要包含的变量 $null
在其他情况下。 修复上述优化错误将有助于解决问题中的情况,但可能还有其他陷阱。
关于powershell - 为什么 [NullString]::Value 使用断点进行不同的评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51294535/