powershell - Why does [NullString]::Value evaluate differently with a breakpoint?
问题描述
I've tried this code in PowerShell ISE and VS Code with the same strange result. Without a breakpoint, the output is EMPTY
, but with a breakpoint in the line with "NULL"
, the output is NULL
(as expected). Why?
function demo {
param(
[string] $value = [NullString]::Value
)
if ($null -eq $value) {
"NULL"
} elseif ($value -eq '') {
"EMPTY"
} else {
"$value"
}
}
demo
I know now, that PowerShell will always convert a non-string value (e.g. $null or [NullString]::Value) to an (empty) string, when you use the type modifier [string] for a parameter. Fine, I can live with that, but it's hard to figure that out by yourself, if debugging is so weird in this case.
解决方案
PetSerAl和以前一样多次在对该问题的评论中提供了关键指针:
一个已知的优化错误是最可能的原因(从 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
给.NET 方法string
的-typed 参数- 见下文。
至于为什么需要使用 of[NullString]::Value
来传递$null
给字符串参数/存储$null
在[string]
变量中,因为 .NET 字符串通常可以直接存储null
( $null
):
根据(历史)设计,当您将 PowerShell分配给变量时,它会转换$null
为(空字符串);这是理由:''
[string]
从https://github.com/PowerShell/PowerShell/issues/4616#issuecomment-323530442:
设计背后的想法是,在大多数
$null
情况下,空字符串都表示相同的错误条件,并且在区别很重要的极少数情况下,$PSBoundParameters
足以区分是否知道提供了值。
鉴于在将参数传递给-typed .NET 方法时,即使$null
直接传递也会执行转换''
string
,因此您无法传递null
到 v2 之前的此类方法。
为了解决这个问题,版本 3 引入了[NullString]::Value
,它明确表示希望传递$null
字符串上下文。
(替代方案 - 使 PowerShell 字符串默认$null
并允许直接分配$null
- 被认为是会破坏太多现有脚本的更改。)
考虑到 PowerShell 不希望变量包含在其他上下文中,使用 [NullString]::Value
超出其预期目的(即,传递null
给.NET 方法中的参数)是有问题的。string
[string]
$null
修复上述优化错误将有助于解决问题中的情况,但可能还有其他陷阱。
推荐阅读
- python - 如何在 Pycharm 上显示 SQL 表
- python - Tensorflow 未使用检测边界框进行训练
- javascript - res.send() 大字符串时Nodejs服务器崩溃
- java - 如何从 arcore 点云中获取 ply 格式文件?
- javascript - 如何使用javascript onclick更改输入字段?
- javacc - 在 JavaCC 语法中查找选择冲突的来源
- python - docopt 不解析 args,只打印使用情况
- python - 使用搜索框从网站中抓取数据
- python - 访问方法内的变量
- python - pip 是否为包中的特定文件提供不受新版本包影响的任何方法?