为什么[NullString] :: Value使用断点进行不同的求值?

and*_*iDo 5 debugging powershell breakpoints null-string

我在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
Run Code Online (Sandbox Code Playgroud)

我现在知道,当你对参数使用类型修饰符[string]时,PowerShell总是将非字符串值(例如$ null或[NullString] :: Value)转换为(空)字符串.好吧,我可以忍受这一点,但是如果调试在这种情况下如此奇怪,那么很难自己解决这个问题.

mkl*_*nt0 3

PetSerAl与之前多次一样,在对该问题的评论中提供了关键的指针:

\n\n

已知的优化错误是最可能的原因(从 Windows PowerShell v5.1/PowerShell Core v6.1.0 开始),并且当代码在 Visual Studio Code 或 ISE调试器中运行时,该错误恰好被掩盖

\n\n

因此,您可以使用链接的错误报告中提到的相同解决方法Remove-Variable:对函数体中的任何位置进行调用(它的存在就足够了 - 实际上不需要在运行时进行调用):

\n\n
function demo {\n    param(\n        [string] $value = [NullString]::Value\n    )\n\n    # Workaround for optimization bug\n    if ($False) { Remove-Variable }\n\n    if ($null -eq $value) {\n        "NULL"\n    } elseif ($value -eq \'\') {\n        "EMPTY"\n    } else {\n        "$value"\n    }\n}\n\ndemo\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,无论是否调试,您都会得到一致的"NULL"输出。

\n\n

但是,最好限制[NullString]::Value其设计用途:传递null.NET 方法string的类型化参数- 见下文。

\n\n
\n\n

至于为什么需要使用[NullString]::Value来传递$null给字符串参数/存储$null[string]变量中,因为 .NET 字符串通常可以直接存储null( $null):

\n\n

根据(历史)设计,当您将 PowerShell 分配给变量时,PowerShell 会转换$null\'\'(空字符串)[string];理由如下:

\n\n

来自https://github.com/PowerShell/PowerShell/issues/4616#issuecomment-323530442

\n\n
\n

设计背后的想法是,在大多数情况下,\xc2\xa0 $null\xc2\xa0 和空字符串都表示相同的错误条件,并且在极少数情况下,区分很重要,\xc2\xa0$PSBoundParameters足以区分知道是否提供了某个值。

\n
\n\n

鉴于即使在将参数传递给类型化.NET 方法时直接传递也会执行转换$null \'\'string,您也无法传递null到 v2 之前的此类方法。
\n为了解决这个问题,版本 3 引入了[NullString]::Value,它明确表示希望传递$null字符串上下文。
\n(替代方案 - 将 PowerShell 字符串设置为默认值$null并允许直接分配$null- 被认为是一种会破坏太多现有脚本的更改。)

\n\n

考虑到 PowerShell 不希望变量包含在其他上下文中[NullString]::Value,超出其预期目的(即传递null到.NET 方法中的参数)的使用 是有问题的。string[string]$null

\n\n

修复上述优化错误将对问题中的场景有所帮助,但可能还有其他陷阱。

\n