PowerShell-Fallen #4: Wenn Äpfel Birnen gleichen, aber Birnen nicht Äpfeln

Veröffentlicht am Kategorisiert in PowerShell Keine Kommentare zu PowerShell-Fallen #4: Wenn Äpfel Birnen gleichen, aber Birnen nicht Äpfeln

Mit dem Gleichheitsoperator -eq werden in PowerShell zwei Operanden auf Gleichheit überprüft, wie man es in den meisten anderen Programmiersprachen mit == unternimmt. A == B entspräche darum notwendigerweise B == A.

Type Casting, mal wieder!

In PowerShell kann $A -eq $B aber unter Umständen das Gegenteil von $B -eq $A ergeben! Der Beweis folgt sogleich:

5 -eq $true
$true -eq $5

Output:
False
True

Dem mathematisch-logischen Verstand widerstrebt es zunächst, diese Tatsache zu akzeptieren, aber sie lässt sich wie so oft in PowerShell mit impliziter Typumwandlung erklären.

Der rechte Operand wird in den Typ des linken Operanden konvertiert, und erst danach wird geprüft, ob ihre Werte gleich sind:

5 -eq [int] $true
$true -eq [bool] 5

Output:
False
True

Denn während [bool] jeden Integer-Wert außer 0 (also auch negative Zahlen) zu $true umwandelt, ergibt [int] $true immer 1.

Aus demselben Grund lassen sich übrigens auch Strings und Integers problemlos miteinander vergleichen!

5 -eq "5"
"5" -eq 5

Output:
True
True

Denn auch hier wird implizit konvertiert:

5 -eq [int] "5"
"5" -eq [string] 5

Output:
True
True

In manchen Fällen kann das sehr nützlich sein, aber man sollte diese Funktionsweise immer im Hinterkopf behalten, besonders wenn man wirklich einmal auf Typgleichheit angewiesen ist.

Typstrenge Vergleiche

Die folgende Funktion umgeht die implizite Typumwandlung, indem zuerst der Typ der Operanden und erst danach ihr Wert verglichen wird:

function Compare {
param(
$a,
$b
)

    $(if ($a -eq $null) {$null} else {$a.GetType()}) `
    -eq $(if ($b -eq $null) {$null} else {$b.GetType()}) `
    -and $a -eq $b
}

Compare $true 5
Compare 5 "5"
Compare 3 3

Output:
False
False
True

Von Pascal Korz

IT Systems Engineer in und aus dem schönen Köln

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert