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

为什么$array-eq$null在$array只包含一个$null元素时不计算为$true?[副本]

楚健
2023-03-14

我终于花时间来了解为什么Visual Studio Code让我把$null放在相等比较的左侧。

在处理此行为时,我发现,当将包含$null元素的数组与右侧$null$null进行比较时,“预期的意外行为”发生在包含两个或多个$null元素的数组中,但对于包含单个$null元素的数组则不然。也就是说,如果 ($array -eq $null) { '它等于 $null!' } 输出 如果 $array 包含多个 $null 元素,则等于 $null $array只包含一个元素时,则不等于 $array!导致这种差异的$null元素的数量是多少?

下面的测试代码演示了这种行为...

function TestForNull($description, $value)
{
    $comparisonResult = $value -eq $null;
    $ifEntered = if ($value -eq $null) {
        $true;
    } else {
        $false;
    };

    Write-Host -Object $description;
    Write-Host -Object "`t`$comparisonResult.GetType(): $($comparisonResult.GetType())";
    Write-Host -Object "`t`$comparisonResult.Length: $($comparisonResult.Length)";
    for ($i = 0; $i -lt $comparisonResult.Length; $i++)
    {
        $item = $comparisonResult.GetValue($i);
        $itemText = if ($null -eq $item) {
            '(null)';
        } else {
            $item.ToString();
        };

        Write-Host -Object "`t`$comparisonResult[$i]: $itemText";
    }
    Write-Host -Object "`t`$ifEntered: $ifEntered";
}

TestForNull '0-element array'                          @();
TestForNull '1-element array with all $nulls'          @($null);
TestForNull '2-element array with all $nulls'          @($null, $null);
TestForNull '3-element array with all $nulls'          @($null, $null, $null);
TestForNull '3-element array with one leading $null'   @($null, 2, 3);
TestForNull '3-element array with one inner $null'     @(1, $null, 3);
TestForNull '3-element array with one trailing $null'  @(1, 2, $null);
TestForNull '3-element array with two leading $nulls'  @($null, $null, 3);
TestForNull '3-element array with two boundary $nulls' @($null, 2, $null);
TestForNull '3-element array with two trailing $nulls' @(1, $null, $null);

…和输出。。。

0-element array
        $comparisonResult.GetType(): System.Object[]
        $comparisonResult.Length: 0
        $ifEntered: False
1-element array with all $nulls
        $comparisonResult.GetType(): System.Object[]
        $comparisonResult.Length: 1
        $comparisonResult[0]: (null)
        $ifEntered: False
2-element array with all $nulls
        $comparisonResult.GetType(): System.Object[]
        $comparisonResult.Length: 2
        $comparisonResult[0]: (null)
        $comparisonResult[1]: (null)
        $ifEntered: True
3-element array with all $nulls
        $comparisonResult.GetType(): System.Object[]
        $comparisonResult.Length: 3
        $comparisonResult[0]: (null)
        $comparisonResult[1]: (null)
        $comparisonResult[2]: (null)
        $ifEntered: True
3-element array with one leading $null
        $comparisonResult.GetType(): System.Object[]
        $comparisonResult.Length: 1
        $comparisonResult[0]: (null)
        $ifEntered: False
3-element array with one inner $null
        $comparisonResult.GetType(): System.Object[]
        $comparisonResult.Length: 1
        $comparisonResult[0]: (null)
        $ifEntered: False
3-element array with one trailing $null
        $comparisonResult.GetType(): System.Object[]
        $comparisonResult.Length: 1
        $comparisonResult[0]: (null)
        $ifEntered: False
3-element array with two leading $nulls
        $comparisonResult.GetType(): System.Object[]
        $comparisonResult.Length: 2
        $comparisonResult[0]: (null)
        $comparisonResult[1]: (null)
        $ifEntered: True
3-element array with two boundary $nulls
        $comparisonResult.GetType(): System.Object[]
        $comparisonResult.Length: 2
        $comparisonResult[0]: (null)
        $comparisonResult[1]: (null)
        $ifEntered: True
3-element array with two trailing $nulls
        $comparisonResult.GetType(): System.Object[]
        $comparisonResult.Length: 2
        $comparisonResult[0]: (null)
        $comparisonResult[1]: (null)
        $ifEntered: True

共有1个答案

方和顺
2023-03-14

我们已经(希望)知道$array-eq$null计算结果不是[Boolean],而是包含$array元素的数组,这些元素等于$null。作为if语句的条件,生成的数组必须转换为[Boolean],尽管我找不到任何官方PowerShell留档详细说明这种情况是如何发生的,但正是这种转换的特殊性导致了相关行为。最好不要用if语句来说明这一点,而只需用强制转换html" target="_blank">表达式…

PS> [Boolean] @()
False
PS> [Boolean] @($null)
False
PS> [Boolean] @($null, $null)
True
PS> [Boolean] @($null, $null, $null)
True
PS> [Boolean] @(New-Object -TypeName 'Object')
True
PS> [Boolean] @((New-Object -TypeName 'Object'), (New-Object -TypeName 'Object'))
True
PS> [Boolean] @($true)
True
PS> [Boolean] @($false)
False
PS> [Boolean] @($true, $true)
True
PS> [Boolean] @($true, $false)
True
PS> [Boolean] @($false, $true)
True
PS> [Boolean] @($false, $false)
True
PS> [Boolean] @(0)
False
PS> [Boolean] @(1)
True
PS> [Boolean] @(-1)
True
PS> [Boolean] @('')
False
PS> [Boolean] @('false')
True
PS> [Boolean] @('true')
True
PS> [Boolean] @('1')
True
PS> [Boolean] @('0')
True
PS> [Boolean] @('-1')
True

如果那里没有可识别的模式,逻辑是...

    < li >空数组被转换为< code>$false。 < li >只有一个元素的数组被转换为... < ul > <李>...如果该元素实现< code>IList接口,则该元素的长度为< code>[Boolean]。 <李>...如果该元素没有实现< code>IList接口,则将该元素转换为< code>[Boolean]的结果。

因此,假设$array包含一个$null元素(例如$$array=@($null)),$array-eq$null返回@($null)。当将@($null)转换为[布尔值]时,上述规则2适用:$null将转换为$false,因此@($null)将转换为$false

给定$array包含多个$null元素(例如$array=@($null,$null)),$array-eq$null返回一个具有相同数量(最重要的是,多个)$null元素的数组。$null转换为$false的事实在这里无关紧要,因为根据规则3,此类数组总是转换为$true

这就是为什么一个数组包含一个或多个<code>$null

补充阅读:

  • IsTrue()方法重载的System.Management.Automation.LanguagePrimitives
  • 为什么在测试PSCustomObject的属性时操作数的顺序很重要
  • 比较运算符、集合和条件(Oh, My!)
  • 在Powershell中将对象转换为布尔值
  • 布尔值和运算符
  • PowerShell-揭秘空比较

 类似资料:
  • 我遇到了一个有趣的问题,我试图为 分配一个ref,所以我有一个 并将它放在我的

  • 语法糖,queryData()方法等同于query()->getData()->all() 可能你会觉的列表采集的语法有一点点繁琐,如: $rt = QueryList::get($url)->rules($rules)->query()->getData(); print_r($rt->all()); QueryList V4.0.4版本新增了一个queryData()语法糖来简化这种操作: $

  • 问题内容: 我正在阅读本文: 在SQL中获取null == null 共识是,当尝试测试两个(可空)sql列之间的相等性时,正确的方法是: 当A和B为时,(A = B)仍返回FALSE,因为NULL不等于NULL。这就是为什么需要额外检查的原因。 检验不平等情况如何?经过以上讨论,我认为要测试不平等,我需要做一些类似的事情: 但是,我注意到这不是必需的(至少在informix 11.5上没有),我

  • 问题内容: 当具有边距的元素包含在另一个元素中时,父级不会始终包裹/包含该边距。 许多事情将导致父母控制孩子的保证金: (这只是经过一点测试,毫无疑问,还有更多。) 我认为这与利润下降有关,但是: W3C规范页面没有此类行为的描述。 这里没有重叠的边距。 在此问题上,所有浏览器的行为似乎都是一致的。 该行为受到与边距无关的触发器的影响。 根据逻辑,默认元素应包含与溢出设置为自动元素不同的材料? 为

  • 问题内容: 我必须编写一个例程,如果变量的类型为,则将变量的值加1,否则将变量的值分配为0,其中变量的初始值为或。 第一个实现是因为我认为没有数字会使算术表达式为假,但是由于计算为真,所以这是错误的。然后,我得知行为类似于0,并且以下表达式均被评估为true。 当然不是0。被评估为false。这使看似重言式的表达成为错误。 为什么实际上不是0,却像0? 问题答案: 您真正的问题似乎是: 为什么:

  • 问题内容: 在我的Web应用程序中,我在Apache Tomcat(TomEE)/7.0.37服务器上使用OpenJPA。我使用Netbeans自动生成类(“来自数据库的实体类…”和“来自实体类的会话Bean …”)。在SessionBean(例如UserFacade)上,我想获取EntityManager: 但是当我通过上述方式得到它时,我得到的是空值。当我通过: ecm不为空,还可以 我的pe