我已经在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)转换为(空)字符串。 很好,我可以接受,但是如果在这种情况下调试是如此怪异,那么很难自己弄清楚。
答案 0 :(得分:1)
PetSerAl多次在问题评论中提供了关键的指针:
known optimization bug是最可能的原因(从Windows PowerShell v5.1 / PowerShell Core v6.1.0开始),而该错误恰好被掩盖当代码在Visual Studio代码或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
类型的参数 -见下文。
关于为什么要使用[NullString]::Value
才能将$null
传递给字符串参数/将$null
存储在[string]
变量中,因为.NET字符串通常可以直接存储null
($null
):
通过(历史)设计,当您将$null
分配给''
变量时,PowerShell将[string]
转换为$null
(空字符串);这是基本原理:
来自https://github.com/PowerShell/PowerShell/issues/4616#issuecomment-323530442:
设计背后的想法是,在大多数情况下,
$PSBoundParameters
和空字符串都代表相同的错误情况,并且在极少数情况下区别很重要的情况下,null
就足以区分知道是否提供了值。
鉴于even passing $null
directly performs conversion to ''
when passing arguments to string
-typed .NET methods,您无法将[NullString]::Value
传递给v2以下的此类方法。
为了解决这个问题,版本3引入了$null
,它明确表示希望在字符串上下文中传递$null
。
(另一种选择-将PowerShell字符串默认为$null
并允许直接分配[NullString]::Value
-被认为是会破坏太多现有脚本的更改。)
使用null
超出了预期的用途-即,将string
传递给.NET方法中的[string]
参数-会遇到问题,因为PowerShell不会期望{{ 1}}变量在其他情况下包含$null
。
修复上述优化错误将有助于解决该问题,但可能还会有其他陷阱。
答案 1 :(得分:0)
$ null与“”之间的差异
空字符串与null不同;您需要专门测试 为了那个原因。 Null是对象的不存在,而字符串是 一个对象,即使它是空的。
这是PowerShell中的常见陷阱。无论出于什么原因,它都不会 让您将$ null值分配给字符串变量(或字符串) .NET类型的参数);它被转换为空字符串。这个 调用处理null和.net的.NET方法时可能会引起一些头痛 空字符串有所不同,这就是为什么它们后来在v3中添加的原因(如果我 请记住正确),[System.Management.Automation.NullString] 类。如果要调用这种方法,请执行以下操作:
[SomeClass] :: SomeMethod([nullstring] :: Value)
[string] $ camp = $ null
将$ Null分配给$ Camp,但是由于[string]部分强制$ camp 如果是字符串类型,将为$ Camp分配值 [String] $ Null
[String] $ Null将强制转换$ Null(基本上是 不存在的对象)添加到字符串中,并在PowerShell中导致 空字符串。
就PowerShell而言,基本上是正确的。然而, 在.NET Framework中,字符串实际上可以为null,并且有一个 空字符串引用和空字符串之间的区别。 有时,当您查看.NET时,会引起混乱 文档并想知道为什么它似乎无法正常工作 PowerShell。
使用[string] :: IsNullOrEmpty($ variable)
https://powershell.org/forums/topic/difference-between-null-and/
另请参阅...
如何在PowerShell中检查字符串是否为空或为空? [string] :: IsNullOrEmpty(...)
*更新*
将代码更改为此...
function demo {
param(
[string]$value
)
if ([string]::IsNullOrEmpty($value))
{
"NULL"
} elseif ($value -eq '') {
"EMPTY"
} else {
"$value"
}
}
无论是否进行调试(将断点设置为'NULL'和'EMPTY'),返回的结果在我的系统ISE / VSCode上都是相同的
# Results
demo
NULL
demo -value ''
NULL
demo -value ' '
demo -value test
test
*修改为显示elseif处理空格*
具有或符合上述条件
function demo {
param(
[string]$value
)
if ([string]::IsNullOrEmpty($value))
{
"NULL"
} elseif ([string]::IsNullOrWhiteSpace($value)) {
"EMPTY or a White Space"
} else {
"$value"
}
}
# Results
demo
NULL
demo -value ''
NULL
demo -value ' '
EMPTY or a White Space
demo -value test
test