当前位置: 首页 > 知识库问答 >
问题:

为什么[NullString]::Value的计算结果与断点不同?

樊桐
2023-03-14

我在PowerShell ISE和VS代码中尝试了这段代码,得到了同样奇怪的结果。如果没有断点,则输出为空,但如果在带有“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)转换为(空)字符串。好吧,我可以接受,但如果调试在这种情况下如此奇怪,那么很难自己弄清楚。

共有2个答案

楚硕
2023-03-14

$null和“”之间的差异

空字符串与null不同;你需要专门为此进行测试。Null表示对象不存在,而字符串是对象,即使它是空的。

这是PowerShell中常见的问题。无论出于何种原因,它都不允许您将$null值分配给字符串变量(或将字符串参数分配给.NET类型);它被转换为空字符串。打电话时,这可能会引起一些头痛。NET方法对null和空字符串的处理方式不同,这就是为什么它们后来(如果我没记错的话,在v3中)添加了[System.Management.Automation.NullString]类。如果要调用此类方法,请执行以下操作:

::::值

[字符串]$camp=$null

将$Null分配给$Camp,但由于[字符串]部分强制$Camp为字符串类型,因此将为$Camp分配[字符串]$Null的值

[String]$Null将强制$Null(基本上是一个不存在的对象)转换为字符串,并在PowerShell中导致空字符串。

就PowerShell而言,这基本上是正确的。然而,在。NET框架中,字符串实际上可以为null,并且null字符串引用和空字符串之间存在差异。有时,当你看的时候,这会引起混淆。NET文档,并想知道为什么它在PowerShell中似乎不能正常工作。

使用[string]::IsNullOr空($变量)

https://powershell.org/forums/topic/difference-between-null-and/

另见...

如何在PowerShell中检查字符串是否为null或空?[字符串]::IsNullOrEmpty(…)

如何在PowerShell中检查字符串是否为null或空?

*更新*

将您的代码更改为此...

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
江浩慨
2023-03-14

佩瑟拉尔(PetSerAl)像以前一样多次在对这个问题的评论中提供了关键的指针:

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

因此,您可以使用链接错误报告中提到的相同解决方法:在函数体的任何位置调用Remve-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方法-请参见下文。

至于为什么需要使用[NullString]::Value才能将$null传递给[string]变量中的字符串参数/store$null,给定。NET字符串通常可以直接存储null$null):

通过(历史)设计,当您将其分配给[string]变量时,PowerShell会将$null转换为"(空字符串);理由如下:

从…起https://github.com/PowerShell/PowerShell/issues/4616#issuecomment-323530442:

设计背后的想法是,在大多数情况下,

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

使用::Value超出其预期用途-即,用于将参数传递给中的字符串。NET方法-是有问题的,因为PowerShell不希望变量在其他上下文中包含null。

修复上述优化bug将有助于解决问题中的场景,但可能还有其他陷阱。

 类似资料:
  • 问题内容: 这是一个有关使用haversine公式计算地球上两个纬度和经度之间的距离的问题,用于需要“查找我最近的”功能的项目中。 haversine公式很好地讨论并在MySQL解决了这个帖子。 然后,我问了一个有关将其转换为存储函数的问题,这样它就可以在以后的项目中使用,而不必查找,记住或重新键入长格式的公式。 都很好。除了我的函数的结果(略有不同)以外,其他条件相同时,直接在查询中直接键入公式

  • 下面的代码通过使用特征向量作为容器或简单的C数组来实现相同的计算。它产生一个封闭的但不是位到位等效的结果。 最后的数学运算是。

  • 问题内容: 为什么评估为无?我预计 问题答案: 这是因为append不返回任何内容(= )。

  • 问题内容: 我尝试将matlab代码转换为numpy,并发现numpy与std函数的结果不同。 在matlab中 在numpy中 这正常吗?我应该如何处理呢? 问题答案: NumPy函数采用一个可选参数:“自由度增量”。默认情况下是。对其进行设置以获取MATLAB结果: 要添加更多上下文,在计算方差(标准偏差为平方根)时,通常将其除以我们拥有的值的数量。 但是,如果我们从较大的分布中选择元素的随机

  • 我这样问是因为我知道检查列表是否为空的python方法如下: 将打印,等等。因此,这导致我用真值识别;但是,如果我试图“直接”比较[]和False,我会得到以下结果: 等 这到底是怎么回事?我觉得我错过了一些非常明显的东西。

  • 为什么运算符只应该是4个字节却生成12个字节?当我引用变量时,这只是引用数组第一个索引的内存地址。实际上,我打印了第一个索引的内存地址,并将其与进行了比较,它们产生了相同的内存地址结果,这证实了它们都引用了数组的第一个索引,但是“array”产生了12个字节,而产生了4个字节。