vendredi 21 décembre 2018

Why does $array -eq $null not evaluate to $true when $array contains only one $null element?

I'm finally taking the time to understand why Visual Studio Code nags me to put $null on the left side of equality comparisons.

In playing around with this behavior, I found that when comparing an array containing $null elements to $null with $null on the right side, the "expected unexpected behavior" occurs with arrays containing two or more $null elements but not for arrays containing a single $null element. That is, if ($array -eq $null) { 'It equals $null!' } outputs It equals $null! if $array contains multiple $null elements, but not when $array contains only one. What is it about the number of $null elements that causes this discrepancy?

The following test code demonstrates this behavior...

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);

...and outputs...

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

Aucun commentaire:

Enregistrer un commentaire